* [PATCH v2 1/7] hw/sd/sdcard: Introduce sd_cmd_to_receivingdata / sd_generic_write_byte
2024-06-27 16:33 [PATCH v2 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
@ 2024-06-27 16:33 ` Philippe Mathieu-Daudé
2024-06-27 16:33 ` [PATCH v2 2/7] hw/sd/sdcard: Duplicate WRITE_SINGLE_BLOCK / WRITE_MULTIPLE_BLOCK cases Philippe Mathieu-Daudé
` (5 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-27 16:33 UTC (permalink / raw)
To: qemu-devel
Cc: Sai Pavan Boddu, Luc Michel, Francisco Iglesias, Bin Meng,
qemu-block, Philippe Mathieu-Daudé, Cédric Le Goater,
Joel Stanley
All commands switching from TRANSFER state to (receiving)DATA
do the same: receive stream of data from the DAT lines. Instead
of duplicating the same code many times, introduce 2 helpers:
- sd_cmd_to_receivingdata() on the I/O line setup the data to
be received on the data[] buffer,
- sd_generic_write_byte() on the DAT lines to push the data.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index cd308e9a89..690a3f275e 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1100,6 +1100,22 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req)
return sd_illegal;
}
+/* Configure fields for following sd_generic_write_byte() calls */
+__attribute__((unused))
+static sd_rsp_type_t sd_cmd_to_receivingdata(SDState *sd, SDRequest req,
+ uint64_t start, size_t size)
+{
+ if (sd->state != sd_transfer_state) {
+ return sd_invalid_state_for_cmd(sd, req);
+ }
+ sd->state = sd_receivingdata_state;
+ sd->data_start = start;
+ sd->data_offset = 0;
+ /* sd->data[] used as receive buffer */
+ sd->data_size = size ?: sizeof(sd->data);
+ return sd_r1;
+}
+
/* Configure fields for following sd_generic_read_byte() calls */
static sd_rsp_type_t sd_cmd_to_sendingdata(SDState *sd, SDRequest req,
uint64_t start,
@@ -1953,6 +1969,19 @@ send_response:
return rsplen;
}
+/* Return true if buffer is consumed. Configured by sd_cmd_to_receivingdata() */
+__attribute__((unused))
+static bool sd_generic_write_byte(SDState *sd, uint8_t value)
+{
+ sd->data[sd->data_offset] = value;
+
+ if (++sd->data_offset >= sd->data_size) {
+ sd->state = sd_transfer_state;
+ return true;
+ }
+ return false;
+}
+
/* Return true when buffer is consumed. Configured by sd_cmd_to_sendingdata() */
static bool sd_generic_read_byte(SDState *sd, uint8_t *value)
{
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 2/7] hw/sd/sdcard: Duplicate WRITE_SINGLE_BLOCK / WRITE_MULTIPLE_BLOCK cases
2024-06-27 16:33 [PATCH v2 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
2024-06-27 16:33 ` [PATCH v2 1/7] hw/sd/sdcard: Introduce sd_cmd_to_receivingdata / sd_generic_write_byte Philippe Mathieu-Daudé
@ 2024-06-27 16:33 ` Philippe Mathieu-Daudé
2024-06-27 16:33 ` [PATCH v2 3/7] hw/sd/sdcard: Convert WRITE_SINGLE_BLOCK to generic_write_byte (CMD24) Philippe Mathieu-Daudé
` (4 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-27 16:33 UTC (permalink / raw)
To: qemu-devel
Cc: Sai Pavan Boddu, Luc Michel, Francisco Iglesias, Bin Meng,
qemu-block, Philippe Mathieu-Daudé, Cédric Le Goater,
Joel Stanley
In order to modify the WRITE_SINGLE_BLOCK case in the
next commit, duplicate it first.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 690a3f275e..5dbfc8000b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1461,6 +1461,35 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
/* Block write commands (Class 4) */
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
+ addr = sd_req_get_address(sd, req);
+ switch (sd->state) {
+ case sd_transfer_state:
+
+ if (!address_in_range(sd, "WRITE_SINGLE_BLOCK", addr,
+ sd->blk_len)) {
+ return sd_r1;
+ }
+
+ sd->state = sd_receivingdata_state;
+ sd->data_start = addr;
+ sd->data_offset = 0;
+
+ if (sd->size <= SDSC_MAX_CAPACITY) {
+ if (sd_wp_addr(sd, sd->data_start)) {
+ sd->card_status |= WP_VIOLATION;
+ }
+ }
+ if (sd->csd[14] & 0x30) {
+ sd->card_status |= WP_VIOLATION;
+ }
+ sd->blk_written = 0;
+ return sd_r1;
+
+ default:
+ break;
+ }
+ break;
+
case 25: /* CMD25: WRITE_MULTIPLE_BLOCK */
addr = sd_req_get_address(sd, req);
switch (sd->state) {
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 3/7] hw/sd/sdcard: Convert WRITE_SINGLE_BLOCK to generic_write_byte (CMD24)
2024-06-27 16:33 [PATCH v2 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
2024-06-27 16:33 ` [PATCH v2 1/7] hw/sd/sdcard: Introduce sd_cmd_to_receivingdata / sd_generic_write_byte Philippe Mathieu-Daudé
2024-06-27 16:33 ` [PATCH v2 2/7] hw/sd/sdcard: Duplicate WRITE_SINGLE_BLOCK / WRITE_MULTIPLE_BLOCK cases Philippe Mathieu-Daudé
@ 2024-06-27 16:33 ` Philippe Mathieu-Daudé
2024-06-27 16:34 ` [PATCH v2 4/7] hw/sd/sdcard: Convert PROGRAM_CID to generic_write_byte (CMD26) Philippe Mathieu-Daudé
` (3 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-27 16:33 UTC (permalink / raw)
To: qemu-devel
Cc: Sai Pavan Boddu, Luc Michel, Francisco Iglesias, Bin Meng,
qemu-block, Philippe Mathieu-Daudé, Cédric Le Goater,
Joel Stanley
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 5dbfc8000b..4a03f41086 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1101,7 +1101,6 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req)
}
/* Configure fields for following sd_generic_write_byte() calls */
-__attribute__((unused))
static sd_rsp_type_t sd_cmd_to_receivingdata(SDState *sd, SDRequest req,
uint64_t start, size_t size)
{
@@ -1470,10 +1469,6 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
return sd_r1;
}
- sd->state = sd_receivingdata_state;
- sd->data_start = addr;
- sd->data_offset = 0;
-
if (sd->size <= SDSC_MAX_CAPACITY) {
if (sd_wp_addr(sd, sd->data_start)) {
sd->card_status |= WP_VIOLATION;
@@ -1483,7 +1478,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
sd->card_status |= WP_VIOLATION;
}
sd->blk_written = 0;
- return sd_r1;
+ return sd_cmd_to_receivingdata(sd, req, addr, sd->blk_len);
default:
break;
@@ -1999,7 +1994,6 @@ send_response:
}
/* Return true if buffer is consumed. Configured by sd_cmd_to_receivingdata() */
-__attribute__((unused))
static bool sd_generic_write_byte(SDState *sd, uint8_t value)
{
sd->data[sd->data_offset] = value;
@@ -2045,8 +2039,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
sd->current_cmd, sd->data_offset, value);
switch (sd->current_cmd) {
case 24: /* CMD24: WRITE_SINGLE_BLOCK */
- sd->data[sd->data_offset ++] = value;
- if (sd->data_offset >= sd->blk_len) {
+ if (sd_generic_write_byte(sd, value)) {
/* TODO: Check CRC before committing */
sd->state = sd_programming_state;
sd_blk_write(sd, sd->data_start, sd->data_offset);
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 4/7] hw/sd/sdcard: Convert PROGRAM_CID to generic_write_byte (CMD26)
2024-06-27 16:33 [PATCH v2 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2024-06-27 16:33 ` [PATCH v2 3/7] hw/sd/sdcard: Convert WRITE_SINGLE_BLOCK to generic_write_byte (CMD24) Philippe Mathieu-Daudé
@ 2024-06-27 16:34 ` Philippe Mathieu-Daudé
2024-06-27 16:34 ` [PATCH v2 5/7] hw/sd/sdcard: Convert PROGRAM_CSD to generic_write_byte (CMD27) Philippe Mathieu-Daudé
` (2 subsequent siblings)
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-27 16:34 UTC (permalink / raw)
To: qemu-devel
Cc: Sai Pavan Boddu, Luc Michel, Francisco Iglesias, Bin Meng,
qemu-block, Philippe Mathieu-Daudé, Cédric Le Goater,
Joel Stanley
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 4a03f41086..b9c72a0128 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1515,17 +1515,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
break;
case 26: /* CMD26: PROGRAM_CID */
- switch (sd->state) {
- case sd_transfer_state:
- sd->state = sd_receivingdata_state;
- sd->data_start = 0;
- sd->data_offset = 0;
- return sd_r1;
-
- default:
- break;
- }
- break;
+ return sd_cmd_to_receivingdata(sd, req, 0, sizeof(sd->cid));
case 27: /* CMD27: PROGRAM_CSD */
switch (sd->state) {
@@ -2088,8 +2078,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
break;
case 26: /* CMD26: PROGRAM_CID */
- sd->data[sd->data_offset ++] = value;
- if (sd->data_offset >= sizeof(sd->cid)) {
+ if (sd_generic_write_byte(sd, value)) {
/* TODO: Check CRC before committing */
sd->state = sd_programming_state;
for (i = 0; i < sizeof(sd->cid); i ++)
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 5/7] hw/sd/sdcard: Convert PROGRAM_CSD to generic_write_byte (CMD27)
2024-06-27 16:33 [PATCH v2 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2024-06-27 16:34 ` [PATCH v2 4/7] hw/sd/sdcard: Convert PROGRAM_CID to generic_write_byte (CMD26) Philippe Mathieu-Daudé
@ 2024-06-27 16:34 ` Philippe Mathieu-Daudé
2024-06-27 16:34 ` [PATCH v2 6/7] hw/sd/sdcard: Convert LOCK_UNLOCK to generic_write_byte (CMD42) Philippe Mathieu-Daudé
2024-06-27 16:34 ` [PATCH v2 7/7] hw/sd/sdcard: Convert GEN_CMD to generic_write_byte (CMD56) Philippe Mathieu-Daudé
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-27 16:34 UTC (permalink / raw)
To: qemu-devel
Cc: Sai Pavan Boddu, Luc Michel, Francisco Iglesias, Bin Meng,
qemu-block, Philippe Mathieu-Daudé, Cédric Le Goater,
Joel Stanley
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index b9c72a0128..bdd5f3486a 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1518,17 +1518,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
return sd_cmd_to_receivingdata(sd, req, 0, sizeof(sd->cid));
case 27: /* CMD27: PROGRAM_CSD */
- switch (sd->state) {
- case sd_transfer_state:
- sd->state = sd_receivingdata_state;
- sd->data_start = 0;
- sd->data_offset = 0;
- return sd_r1;
-
- default:
- break;
- }
- break;
+ return sd_cmd_to_receivingdata(sd, req, 0, sizeof(sd->csd));
/* Write protection (Class 6) */
case 28: /* CMD28: SET_WRITE_PROT */
@@ -2096,8 +2086,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
break;
case 27: /* CMD27: PROGRAM_CSD */
- sd->data[sd->data_offset ++] = value;
- if (sd->data_offset >= sizeof(sd->csd)) {
+ if (sd_generic_write_byte(sd, value)) {
/* TODO: Check CRC before committing */
sd->state = sd_programming_state;
for (i = 0; i < sizeof(sd->csd); i ++)
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 6/7] hw/sd/sdcard: Convert LOCK_UNLOCK to generic_write_byte (CMD42)
2024-06-27 16:33 [PATCH v2 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2024-06-27 16:34 ` [PATCH v2 5/7] hw/sd/sdcard: Convert PROGRAM_CSD to generic_write_byte (CMD27) Philippe Mathieu-Daudé
@ 2024-06-27 16:34 ` Philippe Mathieu-Daudé
2024-06-27 16:34 ` [PATCH v2 7/7] hw/sd/sdcard: Convert GEN_CMD to generic_write_byte (CMD56) Philippe Mathieu-Daudé
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-27 16:34 UTC (permalink / raw)
To: qemu-devel
Cc: Sai Pavan Boddu, Luc Michel, Francisco Iglesias, Bin Meng,
qemu-block, Philippe Mathieu-Daudé, Cédric Le Goater,
Joel Stanley
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 15 ++-------------
1 file changed, 2 insertions(+), 13 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index bdd5f3486a..0cb528b0b2 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1628,17 +1628,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
/* Lock card commands (Class 7) */
case 42: /* CMD42: LOCK_UNLOCK */
- switch (sd->state) {
- case sd_transfer_state:
- sd->state = sd_receivingdata_state;
- sd->data_start = 0;
- sd->data_offset = 0;
- return sd_r1;
-
- default:
- break;
- }
- break;
+ return sd_cmd_to_receivingdata(sd, req, 0, 0);
/* Application specific commands (Class 8) */
case 55: /* CMD55: APP_CMD */
@@ -2109,8 +2099,7 @@ void sd_write_byte(SDState *sd, uint8_t value)
break;
case 42: /* CMD42: LOCK_UNLOCK */
- sd->data[sd->data_offset ++] = value;
- if (sd->data_offset >= sd->blk_len) {
+ if (sd_generic_write_byte(sd, value)) {
/* TODO: Check CRC before committing */
sd->state = sd_programming_state;
sd_lock_command(sd);
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH v2 7/7] hw/sd/sdcard: Convert GEN_CMD to generic_write_byte (CMD56)
2024-06-27 16:33 [PATCH v2 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2024-06-27 16:34 ` [PATCH v2 6/7] hw/sd/sdcard: Convert LOCK_UNLOCK to generic_write_byte (CMD42) Philippe Mathieu-Daudé
@ 2024-06-27 16:34 ` Philippe Mathieu-Daudé
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-27 16:34 UTC (permalink / raw)
To: qemu-devel
Cc: Sai Pavan Boddu, Luc Michel, Francisco Iglesias, Bin Meng,
qemu-block, Philippe Mathieu-Daudé, Cédric Le Goater,
Joel Stanley
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
hw/sd/sd.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 0cb528b0b2..f9708064d0 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1657,14 +1657,12 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, SDRequest req)
case 56: /* CMD56: GEN_CMD */
switch (sd->state) {
case sd_transfer_state:
- sd->data_offset = 0;
if (req.arg & 1) {
return sd_cmd_to_sendingdata(sd, req, 0,
sd->vendor_data,
sizeof(sd->vendor_data));
}
- sd->state = sd_receivingdata_state;
- return sd_r1;
+ return sd_cmd_to_receivingdata(sd, req, 0, sizeof(sd->vendor_data));
default:
break;
@@ -2109,9 +2107,8 @@ void sd_write_byte(SDState *sd, uint8_t value)
break;
case 56: /* CMD56: GEN_CMD */
- sd->vendor_data[sd->data_offset ++] = value;
- if (sd->data_offset >= sizeof(sd->vendor_data)) {
- sd->state = sd_transfer_state;
+ if (sd_generic_write_byte(sd, value)) {
+ memcpy(sd->vendor_data, sd->data, sizeof(sd->vendor_data));
}
break;
--
2.41.0
^ permalink raw reply related [flat|nested] 8+ messages in thread