* [PULL 01/19] bswap: Add st24_be_p() to store 24 bits in big-endian order
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 02/19] hw/sd/sdcard: Avoid OOB in sd_read_byte() during unexpected CMD switch Philippe Mathieu-Daudé
` (18 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Cédric Le Goater,
Richard Henderson
Commit 14180d6221 ("bswap: Add the ability to store to an
unaligned 24 bit field") added st24_le_p() for little
endianness, add st24_be_p() equivalent for bit one.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20240621075607.17902-1-philmd@linaro.org>
---
include/qemu/bswap.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index bd67468e5e..ad22910a5d 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -38,12 +38,14 @@ static inline void bswap64s(uint64_t *s)
#if HOST_BIG_ENDIAN
#define be_bswap(v, size) (v)
#define le_bswap(v, size) glue(__builtin_bswap, size)(v)
+#define be_bswap24(v) (v)
#define le_bswap24(v) bswap24(v)
#define be_bswaps(v, size)
#define le_bswaps(p, size) \
do { *p = glue(__builtin_bswap, size)(*p); } while (0)
#else
#define le_bswap(v, size) (v)
+#define be_bswap24(v) bswap24(v)
#define le_bswap24(v) (v)
#define be_bswap(v, size) glue(__builtin_bswap, size)(v)
#define le_bswaps(v, size)
@@ -357,6 +359,11 @@ static inline void stw_be_p(void *ptr, uint16_t v)
stw_he_p(ptr, be_bswap(v, 16));
}
+static inline void st24_be_p(void *ptr, uint32_t v)
+{
+ st24_he_p(ptr, be_bswap24(v));
+}
+
static inline void stl_be_p(void *ptr, uint32_t v)
{
stl_he_p(ptr, be_bswap(v, 32));
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 02/19] hw/sd/sdcard: Avoid OOB in sd_read_byte() during unexpected CMD switch
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 01/19] bswap: Add st24_be_p() to store 24 bits in big-endian order Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 03/19] hw/sd/sdcard: Correct code indentation Philippe Mathieu-Daudé
` (17 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Alexander Bulekov
For multi-bytes commands, our implementation uses the @data_start
and @data_offset fields to track byte access. We initialize the
command start/offset in buffer once. Malicious guest might abuse
by switching command while staying in the 'transfer' state, switching
command buffer size, and our implementation can access out of buffer
boundary. For example, CMD17 (READ_SINGLE_BLOCK) allows to read up to
512 bytes, and CMD13 (SEND_STATUS) up to 64 bytes. By switching from
CMD17 to CMD13 (see reproducer below), bytes [64-511] are out of the
'status' buffer.
Our implementation return R0 status code for unexpected commands.
Such in-transaction command switch is unexpected and returns R0.
This is a good place to reset the start/offset fields to avoid
malicious accesses.
Can be reproduced running:
$ export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
$ cat << EOF | qemu-system-i386 \
-display none -nographic \
-machine accel=qtest -m 512M \
-nodefaults \
-device sdhci-pci,sd-spec-version=3 \
-device sd-card,drive=mydrive \
-drive if=none,index=0,file=null-co://,format=raw,id=mydrive \
-qtest stdio -trace sd\* -trace -sdbus_read
outl 0xcf8 0x80001010
outl 0xcfc 0xe0000000
outl 0xcf8 0x80001004
outw 0xcfc 0x02
write 0xe000002c 0x1 0x05
write 0xe000000f 0x1 0x37
write 0xe000000a 0x1 0x01
write 0xe000000f 0x1 0x29
write 0xe000000f 0x1 0x02
write 0xe000000f 0x1 0x03
write 0xe000000c 0x1 0x32
write 0xe000000f 0x1 0x06
write 0xe0000005 0x1 0x01
write 0xe0000007 0x1 0x01
write 0xe0000003 0x1 0x00
write 0xe000000f 0x1 0x11
write 0xe000002a 0x1 0x01
write 0xe000002a 0x1 0x02
write 0xe000000f 0x1 0x0d
write 0xe000002a 0x1 0x01
write 0xe000002a 0x1 0x02
EOF
hw/sd/sd.c:1984:15: runtime error: index 256 out of bounds for type 'uint8_t [64]'
#0 sd_read_byte hw/sd/sd.c:1984:15
#1 sdbus_read_data hw/sd/core.c:157:23
#2 sdhci_read_block_from_card hw/sd/sdhci.c:423:9
#3 sdhci_blkgap_write hw/sd/sdhci.c:1074:13
#4 sdhci_write hw/sd/sdhci.c:1195:13
#5 memory_region_write_accessor softmmu/memory.c:492:5
#6 access_with_adjusted_size softmmu/memory.c:554:18
#7 memory_region_dispatch_write softmmu/memory.c
#8 flatview_write_continue softmmu/physmem.c:2778:23
#9 flatview_write softmmu/physmem.c:2818:14
#10 address_space_write softmmu/physmem.c:2910:18
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior hw/sd/sd.c:1984:15
Reported-by: Alexander Bulekov <alxndr@bu.edu>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/487
Buglink: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=36240
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-Id: <20240408141717.66154-2-philmd@linaro.org>
---
hw/sd/sd.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 807b5d3de3..6a7a10501b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1826,6 +1826,13 @@ send_response:
break;
case sd_r0:
+ /*
+ * Invalid state transition, reset implementation
+ * fields to avoid OOB abuse.
+ */
+ sd->data_start = 0;
+ sd->data_offset = 0;
+ /* fall-through */
case sd_illegal:
rsplen = 0;
break;
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 03/19] hw/sd/sdcard: Correct code indentation
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 01/19] bswap: Add st24_be_p() to store 24 bits in big-endian order Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 02/19] hw/sd/sdcard: Avoid OOB in sd_read_byte() during unexpected CMD switch Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 04/19] hw/sd/sdcard: Rewrite sd_cmd_ALL_SEND_CID using switch case (CMD2) Philippe Mathieu-Daudé
` (16 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Fix mis-alignment from commits 793d04f495 and 6380cd2052
("Add sd_cmd_SEND_TUNING_BLOCK" and "Add sd_cmd_SET_BLOCK_COUNT").
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-2-philmd@linaro.org>
---
hw/sd/sd.c | 34 +++++++++++++++++-----------------
1 file changed, 17 insertions(+), 17 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 6a7a10501b..ba7f165cb5 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1069,33 +1069,33 @@ static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
static sd_rsp_type_t sd_cmd_SEND_TUNING_BLOCK(SDState *sd, SDRequest req)
{
- if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
- return sd_cmd_illegal(sd, req);
- }
+ if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
+ return sd_cmd_illegal(sd, req);
+ }
- if (sd->state != sd_transfer_state) {
- return sd_invalid_state_for_cmd(sd, req);
- }
+ if (sd->state != sd_transfer_state) {
+ return sd_invalid_state_for_cmd(sd, req);
+ }
- sd->state = sd_sendingdata_state;
- sd->data_offset = 0;
+ sd->state = sd_sendingdata_state;
+ sd->data_offset = 0;
- return sd_r1;
+ return sd_r1;
}
static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
{
- if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
- return sd_cmd_illegal(sd, req);
- }
+ if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
+ return sd_cmd_illegal(sd, req);
+ }
- if (sd->state != sd_transfer_state) {
- return sd_invalid_state_for_cmd(sd, req);
- }
+ if (sd->state != sd_transfer_state) {
+ return sd_invalid_state_for_cmd(sd, req);
+ }
- sd->multi_blk_cnt = req.arg;
+ sd->multi_blk_cnt = req.arg;
- return sd_r1;
+ return sd_r1;
}
static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 04/19] hw/sd/sdcard: Rewrite sd_cmd_ALL_SEND_CID using switch case (CMD2)
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2024-06-24 13:14 ` [PULL 03/19] hw/sd/sdcard: Correct code indentation Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 05/19] hw/sd/sdcard: Fix typo in SEND_OP_COND command name Philippe Mathieu-Daudé
` (15 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Keep this handler style in sync with other handlers by
using a switch() case, which might become handy to
handle other states.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-3-philmd@linaro.org>
---
hw/sd/sd.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index ba7f165cb5..46388a140a 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1044,13 +1044,13 @@ static sd_rsp_type_t sd_cmd_SEND_OP_CMD(SDState *sd, SDRequest req)
static sd_rsp_type_t sd_cmd_ALL_SEND_CID(SDState *sd, SDRequest req)
{
- if (sd->state != sd_ready_state) {
+ switch (sd->state) {
+ case sd_ready_state:
+ sd->state = sd_identification_state;
+ return sd_r2_i;
+ default:
return sd_invalid_state_for_cmd(sd, req);
}
-
- sd->state = sd_identification_state;
-
- return sd_r2_i;
}
static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 05/19] hw/sd/sdcard: Fix typo in SEND_OP_COND command name
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2024-06-24 13:14 ` [PULL 04/19] hw/sd/sdcard: Rewrite sd_cmd_ALL_SEND_CID using switch case (CMD2) Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 06/19] hw/sd/sdcard: Use HWBLOCK_SHIFT definition instead of magic values Philippe Mathieu-Daudé
` (14 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
There is no SEND_OP_CMD but SEND_OP_COND.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-4-philmd@linaro.org>
---
hw/sd/sd.c | 6 +++---
hw/sd/sdmmc-internal.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 46388a140a..72d71259d3 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1035,7 +1035,7 @@ static sd_rsp_type_t sd_cmd_GO_IDLE_STATE(SDState *sd, SDRequest req)
return sd_is_spi(sd) ? sd_r1 : sd_r0;
}
-static sd_rsp_type_t sd_cmd_SEND_OP_CMD(SDState *sd, SDRequest req)
+static sd_rsp_type_t spi_cmd_SEND_OP_COND(SDState *sd, SDRequest req)
{
sd->state = sd_transfer_state;
@@ -2150,7 +2150,7 @@ static const SDProto sd_proto_spi = {
.name = "SPI",
.cmd = {
[0] = sd_cmd_GO_IDLE_STATE,
- [1] = sd_cmd_SEND_OP_CMD,
+ [1] = spi_cmd_SEND_OP_COND,
[2 ... 4] = sd_cmd_illegal,
[5] = sd_cmd_illegal,
[7] = sd_cmd_illegal,
@@ -2160,7 +2160,7 @@ static const SDProto sd_proto_spi = {
},
.acmd = {
[6] = sd_cmd_unimplemented,
- [41] = sd_cmd_SEND_OP_CMD,
+ [41] = spi_cmd_SEND_OP_COND,
},
};
diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
index 8648a7808d..c1d5508ae6 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", [1] = "SEND_OP_CMD",
+ [0] = "GO_IDLE_STATE", [1] = "SEND_OP_COND",
[2] = "ALL_SEND_CID", [3] = "SEND_RELATIVE_ADDR",
[4] = "SET_DSR", [5] = "IO_SEND_OP_COND",
[6] = "SWITCH_FUNC", [7] = "SELECT/DESELECT_CARD",
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 06/19] hw/sd/sdcard: Use HWBLOCK_SHIFT definition instead of magic values
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2024-06-24 13:14 ` [PULL 05/19] hw/sd/sdcard: Fix typo in SEND_OP_COND command name Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 07/19] hw/sd/sdcard: Use registerfield CSR::CURRENT_STATE definition Philippe Mathieu-Daudé
` (13 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Philippe Mathieu-Daudé,
Cédric Le Goater
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-5-philmd@linaro.org>
---
hw/sd/sd.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 72d71259d3..a14c5ff147 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -596,7 +596,7 @@ static void sd_reset(DeviceState *dev)
} else {
sect = 0;
}
- size = sect << 9;
+ size = sect << HWBLOCK_SHIFT;
sect = sd_addr_to_wpnum(size) + 1;
@@ -822,8 +822,8 @@ static void sd_erase(SDState *sd)
if (FIELD_EX32(sd->ocr, OCR, CARD_CAPACITY)) {
/* High capacity memory card: erase units are 512 byte blocks */
- erase_start *= 512;
- erase_end *= 512;
+ erase_start <<= HWBLOCK_SHIFT;
+ erase_end <<= HWBLOCK_SHIFT;
sdsc = false;
}
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 07/19] hw/sd/sdcard: Use registerfield CSR::CURRENT_STATE definition
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2024-06-24 13:14 ` [PULL 06/19] hw/sd/sdcard: Use HWBLOCK_SHIFT definition instead of magic values Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 08/19] hw/sd/sdcard: Use Load/Store API to fill some CID/CSD registers Philippe Mathieu-Daudé
` (12 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Use registerfield-generated definitions to update card_status.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-6-philmd@linaro.org>
---
hw/sd/sd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index a14c5ff147..64270dec0f 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1788,8 +1788,8 @@ int sd_do_command(SDState *sd, SDRequest *req,
* (Do this now so they appear in r1 responses.)
*/
sd->current_cmd = req->cmd;
- sd->card_status &= ~CURRENT_STATE;
- sd->card_status |= (last_state << 9);
+ sd->card_status = FIELD_DP32(sd->card_status, CSR,
+ CURRENT_STATE, last_state);
}
send_response:
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 08/19] hw/sd/sdcard: Use Load/Store API to fill some CID/CSD registers
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (6 preceding siblings ...)
2024-06-24 13:14 ` [PULL 07/19] hw/sd/sdcard: Use registerfield CSR::CURRENT_STATE definition Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 09/19] hw/sd/sdcard: Remove ACMD6 handler for SPI mode Philippe Mathieu-Daudé
` (11 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
The ld/st API helps noticing CID or CSD bytes refer
to the same field. Multi-bytes fields are stored MSB
first in CID / CSD.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-7-philmd@linaro.org>
---
hw/sd/sd.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 64270dec0f..6e346e28ca 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -393,10 +393,7 @@ static void sd_set_cid(SDState *sd)
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;
+ stl_be_p(&sd->cid[9], 0xdeadbeef); /* Fake serial number (PSN) */
sd->cid[13] = 0x00 | /* Manufacture date (MDT) */
((MDT_YR - 2000) / 10);
sd->cid[14] = ((MDT_YR % 10) << 4) | MDT_MON;
@@ -462,9 +459,7 @@ static void sd_set_csd(SDState *sd, uint64_t size)
sd->csd[4] = 0x5b;
sd->csd[5] = 0x59;
sd->csd[6] = 0x00;
- sd->csd[7] = (size >> 16) & 0xff;
- sd->csd[8] = (size >> 8) & 0xff;
- sd->csd[9] = (size & 0xff);
+ st24_be_p(&sd->csd[7], size);
sd->csd[10] = 0x7f;
sd->csd[11] = 0x80;
sd->csd[12] = 0x0a;
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 09/19] hw/sd/sdcard: Remove ACMD6 handler for SPI mode
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (7 preceding siblings ...)
2024-06-24 13:14 ` [PULL 08/19] hw/sd/sdcard: Use Load/Store API to fill some CID/CSD registers Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 10/19] hw/sd/sdcard: Remove explicit entries for illegal commands Philippe Mathieu-Daudé
` (10 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
There is no ACMD6 command in SPI mode, remove the pointless
handler introduced in commit 946897ce18 ("sdcard: handles
more commands in SPI mode"). Keep sd_cmd_unimplemented()
since we'll reuse it later.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-8-philmd@linaro.org>
---
hw/sd/sd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 6e346e28ca..08a6d0aff8 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1012,6 +1012,7 @@ static sd_rsp_type_t sd_cmd_illegal(SDState *sd, SDRequest req)
}
/* Commands that are recognised but not yet implemented. */
+__attribute__((unused))
static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req)
{
qemu_log_mask(LOG_UNIMP, "%s: CMD%i not implemented\n",
@@ -2154,7 +2155,6 @@ static const SDProto sd_proto_spi = {
[52 ... 54] = sd_cmd_illegal,
},
.acmd = {
- [6] = sd_cmd_unimplemented,
[41] = spi_cmd_SEND_OP_COND,
},
};
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 10/19] hw/sd/sdcard: Remove explicit entries for illegal commands
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (8 preceding siblings ...)
2024-06-24 13:14 ` [PULL 09/19] hw/sd/sdcard: Remove ACMD6 handler for SPI mode Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 11/19] hw/sd/sdcard: Trace update of block count (CMD23) Philippe Mathieu-Daudé
` (9 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
NULL handler is already handled as illegal, no need to
duplicate (that keeps this array simpler to maintain).
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-9-philmd@linaro.org>
---
hw/sd/sd.c | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 08a6d0aff8..4afb6988c7 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -2147,12 +2147,6 @@ static const SDProto sd_proto_spi = {
.cmd = {
[0] = sd_cmd_GO_IDLE_STATE,
[1] = spi_cmd_SEND_OP_COND,
- [2 ... 4] = sd_cmd_illegal,
- [5] = sd_cmd_illegal,
- [7] = sd_cmd_illegal,
- [15] = sd_cmd_illegal,
- [26] = sd_cmd_illegal,
- [52 ... 54] = sd_cmd_illegal,
},
.acmd = {
[41] = spi_cmd_SEND_OP_COND,
@@ -2163,15 +2157,10 @@ static const SDProto sd_proto_sd = {
.name = "SD",
.cmd = {
[0] = sd_cmd_GO_IDLE_STATE,
- [1] = sd_cmd_illegal,
[2] = sd_cmd_ALL_SEND_CID,
[3] = sd_cmd_SEND_RELATIVE_ADDR,
- [5] = sd_cmd_illegal,
[19] = sd_cmd_SEND_TUNING_BLOCK,
[23] = sd_cmd_SET_BLOCK_COUNT,
- [52 ... 54] = sd_cmd_illegal,
- [58] = sd_cmd_illegal,
- [59] = sd_cmd_illegal,
},
};
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 11/19] hw/sd/sdcard: Trace update of block count (CMD23)
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (9 preceding siblings ...)
2024-06-24 13:14 ` [PULL 10/19] hw/sd/sdcard: Remove explicit entries for illegal commands Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 12/19] hw/sd/sdcard: Have cmd_valid_while_locked() return a boolean value Philippe Mathieu-Daudé
` (8 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-12-philmd@linaro.org>
---
hw/sd/sd.c | 1 +
hw/sd/trace-events | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 4afb6988c7..44225bae9b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1090,6 +1090,7 @@ static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
}
sd->multi_blk_cnt = req.arg;
+ trace_sdcard_set_block_count(sd->multi_blk_cnt);
return sd_r1;
}
diff --git a/hw/sd/trace-events b/hw/sd/trace-events
index 94a00557b2..724365efc3 100644
--- a/hw/sd/trace-events
+++ b/hw/sd/trace-events
@@ -43,7 +43,8 @@ sdcard_response(const char *rspdesc, int rsplen) "%s (sz:%d)"
sdcard_powerup(void) ""
sdcard_inquiry_cmd41(void) ""
sdcard_reset(void) ""
-sdcard_set_blocklen(uint16_t length) "0x%03x"
+sdcard_set_blocklen(uint16_t length) "block len 0x%03x"
+sdcard_set_block_count(uint32_t cnt) "block cnt 0x%"PRIx32
sdcard_inserted(bool readonly) "read_only: %u"
sdcard_ejected(void) ""
sdcard_erase(uint32_t first, uint32_t last) "addr first 0x%" PRIx32" last 0x%" PRIx32
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 12/19] hw/sd/sdcard: Have cmd_valid_while_locked() return a boolean value
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (10 preceding siblings ...)
2024-06-24 13:14 ` [PULL 11/19] hw/sd/sdcard: Trace update of block count (CMD23) Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 13/19] hw/sd/sdcard: Factor sd_req_get_rca() method out Philippe Mathieu-Daudé
` (7 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-14-philmd@linaro.org>
---
hw/sd/sd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 44225bae9b..04b141784b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1717,7 +1717,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
return sd_illegal;
}
-static int cmd_valid_while_locked(SDState *sd, const uint8_t cmd)
+static bool cmd_valid_while_locked(SDState *sd, unsigned cmd)
{
/* Valid commands in locked state:
* basic class (0)
@@ -1731,7 +1731,7 @@ static int cmd_valid_while_locked(SDState *sd, const uint8_t cmd)
return cmd == 41 || cmd == 42;
}
if (cmd == 16 || cmd == 55) {
- return 1;
+ return true;
}
return sd_cmd_class[cmd] == 0 || sd_cmd_class[cmd] == 7;
}
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 13/19] hw/sd/sdcard: Factor sd_req_get_rca() method out
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (11 preceding siblings ...)
2024-06-24 13:14 ` [PULL 12/19] hw/sd/sdcard: Have cmd_valid_while_locked() return a boolean value Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 14/19] hw/sd/sdcard: Only call sd_req_get_rca() where RCA is used Philippe Mathieu-Daudé
` (6 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Extract sd_req_get_rca() so we can re-use it in various
SDProto handlers. Return a 16-bit value since RCA is 16-bit.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-15-philmd@linaro.org>
---
hw/sd/sd.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 04b141784b..b909a85d53 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -474,6 +474,14 @@ static void sd_set_rca(SDState *sd)
sd->rca += 0x4567;
}
+static uint16_t sd_req_get_rca(SDState *s, SDRequest req)
+{
+ if (sd_cmd_type[req.cmd] == sd_ac || sd_cmd_type[req.cmd] == sd_adtc) {
+ return req.arg >> 16;
+ }
+ return 0;
+}
+
FIELD(CSR, AKE_SEQ_ERROR, 3, 1)
FIELD(CSR, APP_CMD, 5, 1)
FIELD(CSR, FX_EVENT, 6, 1)
@@ -1097,7 +1105,7 @@ static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
{
- uint32_t rca = 0x0000;
+ uint16_t rca = sd_req_get_rca(sd, req);
uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg;
/* CMD55 precedes an ACMD, so we are not interested in tracing it.
@@ -1112,11 +1120,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
/* Not interpreting this as an app command */
sd->card_status &= ~APP_CMD;
- if (sd_cmd_type[req.cmd] == sd_ac
- || sd_cmd_type[req.cmd] == sd_adtc) {
- rca = req.arg >> 16;
- }
-
/* CMD23 (set block count) must be immediately followed by CMD18 or CMD25
* if not, its effects are cancelled */
if (sd->multi_blk_cnt != 0 && !(req.cmd == 18 || req.cmd == 25)) {
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 14/19] hw/sd/sdcard: Only call sd_req_get_rca() where RCA is used
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (12 preceding siblings ...)
2024-06-24 13:14 ` [PULL 13/19] hw/sd/sdcard: Factor sd_req_get_rca() method out Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 15/19] hw/sd/sdcard: Factor sd_req_get_address() method out Philippe Mathieu-Daudé
` (5 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
It will be useful later to assert only AC commands
(Addressed point-to-point Commands, defined as the
'sd_ac' enum) extract the RCA value from the command
argument.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-16-philmd@linaro.org>
---
hw/sd/sd.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index b909a85d53..912b2f8984 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1105,7 +1105,7 @@ static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
{
- uint16_t rca = sd_req_get_rca(sd, req);
+ uint16_t rca;
uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg;
/* CMD55 precedes an ACMD, so we are not interested in tracing it.
@@ -1162,6 +1162,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 7: /* CMD7: SELECT/DESELECT_CARD */
+ rca = sd_req_get_rca(sd, req);
switch (sd->state) {
case sd_standby_state:
if (sd->rca != rca)
@@ -1216,6 +1217,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
return sd_r7;
case 9: /* CMD9: SEND_CSD */
+ rca = sd_req_get_rca(sd, req);
switch (sd->state) {
case sd_standby_state:
if (sd->rca != rca)
@@ -1239,6 +1241,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 10: /* CMD10: SEND_CID */
+ rca = sd_req_get_rca(sd, req);
switch (sd->state) {
case sd_standby_state:
if (sd->rca != rca)
@@ -1279,6 +1282,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 13: /* CMD13: SEND_STATUS */
+ rca = sd_req_get_rca(sd, req);
switch (sd->mode) {
case sd_data_transfer_mode:
if (!sd_is_spi(sd) && sd->rca != rca) {
@@ -1293,6 +1297,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 15: /* CMD15: GO_INACTIVE_STATE */
+ rca = sd_req_get_rca(sd, req);
switch (sd->mode) {
case sd_data_transfer_mode:
if (sd->rca != rca)
@@ -1525,6 +1530,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
/* Application specific commands (Class 8) */
case 55: /* CMD55: APP_CMD */
+ rca = sd_req_get_rca(sd, req);
switch (sd->state) {
case sd_ready_state:
case sd_identification_state:
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 15/19] hw/sd/sdcard: Factor sd_req_get_address() method out
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (13 preceding siblings ...)
2024-06-24 13:14 ` [PULL 14/19] hw/sd/sdcard: Only call sd_req_get_rca() where RCA is used Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 16/19] hw/sd/sdcard: Only call sd_req_get_address() where address is used Philippe Mathieu-Daudé
` (4 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Extract sd_cmd_get_address() so we can re-use it
in various SDProto handlers. Use CARD_CAPACITY and
HWBLOCK_SHIFT definitions instead of magic values.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-17-philmd@linaro.org>
---
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 912b2f8984..51ab7cd003 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -582,6 +582,14 @@ static void sd_response_r7_make(SDState *sd, uint8_t *response)
stl_be_p(response, sd->vhs);
}
+static uint64_t sd_req_get_address(SDState *sd, SDRequest req)
+{
+ if (FIELD_EX32(sd->ocr, OCR, CARD_CAPACITY)) {
+ return (uint64_t) req.arg << HWBLOCK_SHIFT;
+ }
+ return req.arg;
+}
+
static inline uint64_t sd_addr_to_wpnum(uint64_t addr)
{
return addr >> (HWBLOCK_SHIFT + SECTOR_SHIFT + WPGROUP_SHIFT);
@@ -1106,7 +1114,7 @@ static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
{
uint16_t rca;
- uint64_t addr = (sd->ocr & (1 << 30)) ? (uint64_t) req.arg << 9 : req.arg;
+ uint64_t addr = sd_req_get_address(sd, req);
/* CMD55 precedes an ACMD, so we are not interested in tracing it.
* However there is no ACMD55, so we want to trace this particular case.
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 16/19] hw/sd/sdcard: Only call sd_req_get_address() where address is used
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (14 preceding siblings ...)
2024-06-24 13:14 ` [PULL 15/19] hw/sd/sdcard: Factor sd_req_get_address() method out Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 17/19] hw/sd/sdcard: Add sd_invalid_mode_for_cmd to report invalid mode switch Philippe Mathieu-Daudé
` (3 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
It will be useful later to assert only ADTC commands
(Addressed point-to-point Data Transfer Commands, defined
as the 'sd_adtc' enum) extract the address value from the
command argument.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-18-philmd@linaro.org>
---
hw/sd/sd.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 51ab7cd003..3e4eb656e1 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1114,7 +1114,7 @@ static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
{
uint16_t rca;
- uint64_t addr = sd_req_get_address(sd, req);
+ uint64_t addr;
/* CMD55 precedes an ACMD, so we are not interested in tracing it.
* However there is no ACMD55, so we want to trace this particular case.
@@ -1239,7 +1239,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
sd->state = sd_sendingdata_state;
memcpy(sd->data, sd->csd, 16);
- sd->data_start = addr;
+ sd->data_start = sd_req_get_address(sd, req);
sd->data_offset = 0;
return sd_r1;
@@ -1263,7 +1263,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
}
sd->state = sd_sendingdata_state;
memcpy(sd->data, sd->cid, 16);
- sd->data_start = addr;
+ sd->data_start = sd_req_get_address(sd, req);
sd->data_offset = 0;
return sd_r1;
@@ -1339,6 +1339,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
case 17: /* CMD17: READ_SINGLE_BLOCK */
case 18: /* CMD18: READ_MULTIPLE_BLOCK */
+ addr = sd_req_get_address(sd, req);
switch (sd->state) {
case sd_transfer_state:
@@ -1359,6 +1360,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
/* Block write commands (Class 4) */
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
+ addr = sd_req_get_address(sd, req);
switch (sd->state) {
case sd_transfer_state:
@@ -1417,7 +1419,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
if (sd->size > SDSC_MAX_CAPACITY) {
return sd_illegal;
}
-
+ addr = sd_req_get_address(sd, req);
switch (sd->state) {
case sd_transfer_state:
if (!address_in_range(sd, "SET_WRITE_PROT", addr, 1)) {
@@ -1439,7 +1441,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
if (sd->size > SDSC_MAX_CAPACITY) {
return sd_illegal;
}
-
+ addr = sd_req_get_address(sd, req);
switch (sd->state) {
case sd_transfer_state:
if (!address_in_range(sd, "CLR_WRITE_PROT", addr, 1)) {
@@ -1461,7 +1463,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
if (sd->size > SDSC_MAX_CAPACITY) {
return sd_illegal;
}
-
+ addr = sd_req_get_address(sd, req);
switch (sd->state) {
case sd_transfer_state:
if (!address_in_range(sd, "SEND_WRITE_PROT",
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 17/19] hw/sd/sdcard: Add sd_invalid_mode_for_cmd to report invalid mode switch
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (15 preceding siblings ...)
2024-06-24 13:14 ` [PULL 16/19] hw/sd/sdcard: Only call sd_req_get_address() where address is used Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 18/19] hw/sd/sdcard: Inline BLK_READ_BLOCK / BLK_WRITE_BLOCK macros Philippe Mathieu-Daudé
` (2 subsequent siblings)
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
Having the mode switch displayed help to track incomplete
command implementations.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-19-philmd@linaro.org>
---
hw/sd/sd.c | 75 +++++++++++++++++++++++++++++-------------------------
1 file changed, 41 insertions(+), 34 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 3e4eb656e1..969340e5cb 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -178,6 +178,17 @@ static const char *sd_version_str(enum SDPhySpecificationVersion version)
return sdphy_version[version];
}
+static const char *sd_mode_name(enum SDCardModes mode)
+{
+ static const char *mode_name[] = {
+ [sd_inactive] = "inactive",
+ [sd_card_identification_mode] = "identification",
+ [sd_data_transfer_mode] = "transfer",
+ };
+ assert(mode < ARRAY_SIZE(mode_name));
+ return mode_name[mode];
+}
+
static const char *sd_state_name(enum SDCardStates state)
{
static const char *state_name[] = {
@@ -1018,6 +1029,15 @@ static sd_rsp_type_t sd_invalid_state_for_cmd(SDState *sd, SDRequest req)
return sd_illegal;
}
+static sd_rsp_type_t sd_invalid_mode_for_cmd(SDState *sd, SDRequest req)
+{
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: CMD%i in a wrong mode: %s (spec %s)\n",
+ sd_proto(sd)->name, req.cmd, sd_mode_name(sd->mode),
+ sd_version_str(sd->spec_version));
+
+ return sd_illegal;
+}
+
static sd_rsp_type_t sd_cmd_illegal(SDState *sd, SDRequest req)
{
qemu_log_mask(LOG_GUEST_ERROR, "%s: Unknown CMD%i for spec %s\n",
@@ -1156,18 +1176,14 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
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;
-
- default:
- break;
+ if (sd->mode != sd_data_transfer_mode) {
+ return sd_invalid_mode_for_cmd(sd, req);
}
- break;
+ sd_function_switch(sd, req.arg);
+ sd->state = sd_sendingdata_state;
+ sd->data_start = 0;
+ sd->data_offset = 0;
+ return sd_r1;
case 7: /* CMD7: SELECT/DESELECT_CARD */
rca = sd_req_get_rca(sd, req);
@@ -1291,33 +1307,24 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
case 13: /* CMD13: SEND_STATUS */
rca = sd_req_get_rca(sd, req);
- switch (sd->mode) {
- case sd_data_transfer_mode:
- if (!sd_is_spi(sd) && sd->rca != rca) {
- return sd_r0;
- }
-
- return sd_r1;
-
- default:
- break;
+ if (sd->mode != sd_data_transfer_mode) {
+ return sd_invalid_mode_for_cmd(sd, req);
}
- break;
+ if (!sd_is_spi(sd) && sd->rca != rca) {
+ return sd_r0;
+ }
+
+ return sd_r1;
case 15: /* CMD15: GO_INACTIVE_STATE */
- rca = sd_req_get_rca(sd, req);
- switch (sd->mode) {
- case sd_data_transfer_mode:
- if (sd->rca != rca)
- return sd_r0;
-
- sd->state = sd_inactive_state;
- return sd_r0;
-
- default:
- break;
+ if (sd->mode != sd_data_transfer_mode) {
+ return sd_invalid_mode_for_cmd(sd, req);
}
- break;
+ rca = sd_req_get_rca(sd, req);
+ if (sd->rca == rca) {
+ sd->state = sd_inactive_state;
+ }
+ return sd_r0;
/* Block read commands (Class 2) */
case 16: /* CMD16: SET_BLOCKLEN */
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 18/19] hw/sd/sdcard: Inline BLK_READ_BLOCK / BLK_WRITE_BLOCK macros
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (16 preceding siblings ...)
2024-06-24 13:14 ` [PULL 17/19] hw/sd/sdcard: Add sd_invalid_mode_for_cmd to report invalid mode switch Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-24 13:14 ` [PULL 19/19] hw/sd/sdcard: Add comments around registers and commands Philippe Mathieu-Daudé
2024-06-25 4:30 ` [PULL 00/19] SD/MMC patches for 2024-06-24 Richard Henderson
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Philippe Mathieu-Daudé, Cédric Le Goater
These macros only save 3 chars and make the code harder
to maintain, simply remove them.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-20-philmd@linaro.org>
---
hw/sd/sd.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 969340e5cb..d4e3d079a8 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -819,8 +819,6 @@ 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 APP_WRITE_BLOCK(a, len)
@@ -872,7 +870,7 @@ static void sd_erase(SDState *sd)
continue;
}
}
- BLK_WRITE_BLOCK(erase_addr, erase_len);
+ sd_blk_write(sd, erase_addr, erase_len);
}
}
@@ -1903,7 +1901,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
if (sd->data_offset >= sd->blk_len) {
/* TODO: Check CRC before committing */
sd->state = sd_programming_state;
- BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
+ sd_blk_write(sd, sd->data_start, sd->data_offset);
sd->blk_written ++;
sd->csd[14] |= 0x40;
/* Bzzzzzzztt .... Operation complete. */
@@ -1929,7 +1927,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
if (sd->data_offset >= sd->blk_len) {
/* TODO: Check CRC before committing */
sd->state = sd_programming_state;
- BLK_WRITE_BLOCK(sd->data_start, sd->data_offset);
+ sd_blk_write(sd, sd->data_start, sd->data_offset);
sd->blk_written++;
sd->data_start += sd->blk_len;
sd->data_offset = 0;
@@ -2077,8 +2075,9 @@ uint8_t sd_read_byte(SDState *sd)
break;
case 17: /* CMD17: READ_SINGLE_BLOCK */
- if (sd->data_offset == 0)
- BLK_READ_BLOCK(sd->data_start, io_len);
+ if (sd->data_offset == 0) {
+ sd_blk_read(sd, sd->data_start, io_len);
+ }
ret = sd->data[sd->data_offset ++];
if (sd->data_offset >= io_len)
@@ -2091,7 +2090,7 @@ uint8_t sd_read_byte(SDState *sd)
sd->data_start, io_len)) {
return 0x00;
}
- BLK_READ_BLOCK(sd->data_start, io_len);
+ sd_blk_read(sd, sd->data_start, io_len);
}
ret = sd->data[sd->data_offset ++];
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PULL 19/19] hw/sd/sdcard: Add comments around registers and commands
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (17 preceding siblings ...)
2024-06-24 13:14 ` [PULL 18/19] hw/sd/sdcard: Inline BLK_READ_BLOCK / BLK_WRITE_BLOCK macros Philippe Mathieu-Daudé
@ 2024-06-24 13:14 ` Philippe Mathieu-Daudé
2024-06-25 4:30 ` [PULL 00/19] SD/MMC patches for 2024-06-24 Richard Henderson
19 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-24 13:14 UTC (permalink / raw)
To: qemu-devel
Cc: Philippe Mathieu-Daudé, Philippe Mathieu-Daudé,
Cédric Le Goater
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Tested-by: Cédric Le Goater <clg@redhat.com>
Message-Id: <20240621080554.18986-21-philmd@linaro.org>
---
hw/sd/sd.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index d4e3d079a8..a48010cfc1 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -315,6 +315,8 @@ static uint8_t sd_crc7(const void *message, size_t width)
return shift_reg;
}
+/* Operation Conditions register */
+
#define OCR_POWER_DELAY_NS 500000 /* 0.5ms */
FIELD(OCR, VDD_VOLTAGE_WINDOW, 0, 24)
@@ -364,6 +366,8 @@ static void sd_set_ocr(SDState *sd)
}
}
+/* SD Configuration register */
+
static void sd_set_scr(SDState *sd)
{
sd->scr[0] = 0 << 4; /* SCR structure version 1.0 */
@@ -386,6 +390,8 @@ static void sd_set_scr(SDState *sd)
sd->scr[7] = 0x00;
}
+/* Card IDentification register */
+
#define MID 0xaa
#define OID "XY"
#define PNM "QEMU!"
@@ -411,6 +417,8 @@ static void sd_set_cid(SDState *sd)
sd->cid[15] = (sd_crc7(sd->cid, 15) << 1) | 1;
}
+/* Card-Specific Data register */
+
#define HWBLOCK_SHIFT 9 /* 512 bytes */
#define SECTOR_SHIFT 5 /* 16 kilobytes */
#define WPGROUP_SHIFT 7 /* 2 megs */
@@ -480,6 +488,8 @@ static void sd_set_csd(SDState *sd, uint64_t size)
sd->csd[15] = (sd_crc7(sd->csd, 15) << 1) | 1;
}
+/* Relative Card Address register */
+
static void sd_set_rca(SDState *sd)
{
sd->rca += 0x4567;
@@ -493,6 +503,8 @@ static uint16_t sd_req_get_rca(SDState *s, SDRequest req)
return 0;
}
+/* Card Status register */
+
FIELD(CSR, AKE_SEQ_ERROR, 3, 1)
FIELD(CSR, APP_CMD, 5, 1)
FIELD(CSR, FX_EVENT, 6, 1)
@@ -623,6 +635,8 @@ static void sd_reset(DeviceState *dev)
sect = sd_addr_to_wpnum(size) + 1;
sd->state = sd_idle_state;
+
+ /* card registers */
sd->rca = 0x0000;
sd->size = size;
sd_set_ocr(sd);
@@ -1055,6 +1069,7 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req)
return sd_illegal;
}
+/* CMD0 */
static sd_rsp_type_t sd_cmd_GO_IDLE_STATE(SDState *sd, SDRequest req)
{
if (sd->state != sd_inactive_state) {
@@ -1065,6 +1080,7 @@ static sd_rsp_type_t sd_cmd_GO_IDLE_STATE(SDState *sd, SDRequest req)
return sd_is_spi(sd) ? sd_r1 : sd_r0;
}
+/* CMD1 */
static sd_rsp_type_t spi_cmd_SEND_OP_COND(SDState *sd, SDRequest req)
{
sd->state = sd_transfer_state;
@@ -1072,6 +1088,7 @@ static sd_rsp_type_t spi_cmd_SEND_OP_COND(SDState *sd, SDRequest req)
return sd_r1;
}
+/* CMD2 */
static sd_rsp_type_t sd_cmd_ALL_SEND_CID(SDState *sd, SDRequest req)
{
switch (sd->state) {
@@ -1083,6 +1100,7 @@ static sd_rsp_type_t sd_cmd_ALL_SEND_CID(SDState *sd, SDRequest req)
}
}
+/* CMD3 */
static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
{
switch (sd->state) {
@@ -1097,6 +1115,7 @@ static sd_rsp_type_t sd_cmd_SEND_RELATIVE_ADDR(SDState *sd, SDRequest req)
}
}
+/* CMD19 */
static sd_rsp_type_t sd_cmd_SEND_TUNING_BLOCK(SDState *sd, SDRequest req)
{
if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
@@ -1113,6 +1132,7 @@ static sd_rsp_type_t sd_cmd_SEND_TUNING_BLOCK(SDState *sd, SDRequest req)
return sd_r1;
}
+/* CMD23 */
static sd_rsp_type_t sd_cmd_SET_BLOCK_COUNT(SDState *sd, SDRequest req)
{
if (sd->spec_version < SD_PHY_SPECv3_01_VERS) {
--
2.41.0
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PULL 00/19] SD/MMC patches for 2024-06-24
2024-06-24 13:14 [PULL 00/19] SD/MMC patches for 2024-06-24 Philippe Mathieu-Daudé
` (18 preceding siblings ...)
2024-06-24 13:14 ` [PULL 19/19] hw/sd/sdcard: Add comments around registers and commands Philippe Mathieu-Daudé
@ 2024-06-25 4:30 ` Richard Henderson
19 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2024-06-25 4:30 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
On 6/24/24 06:14, Philippe Mathieu-Daudé wrote:
> The following changes since commit c9ba79baca7c673098361e3a687f72d458e0d18a:
>
> Merge tag 'pull-target-arm-20240622' ofhttps://git.linaro.org/people/pmaydell/qemu-arm into staging (2024-06-22 09:56:49 -0700)
>
> are available in the Git repository at:
>
> https://github.com/philmd/qemu.git tags/sdmmc-20240624
>
> for you to fetch changes up to 76ae9a231487a2b127c90bcb657fd42a1f6c06f8:
>
> hw/sd/sdcard: Add comments around registers and commands (2024-06-24 15:08:40 +0200)
>
> ----------------------------------------------------------------
> SD/MMC patches queue
>
> One fix and various cleanups for the SD card model.
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/9.1 as appropriate.
r~
^ permalink raw reply [flat|nested] 21+ messages in thread