* [PATCH 1/7] hw/sd/sdcard: Introduce sd_cmd_to_receivingdata / sd_generic_write_byte
2024-06-25 7:34 [PATCH 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
@ 2024-06-25 7:34 ` Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 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-25 7:34 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Philippe Mathieu-Daudé, Bin Meng,
Cédric Le Goater
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 | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 2df3c28cb7..7fea0afb62 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1081,6 +1081,21 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req)
return sd_illegal;
}
+__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;
+}
+
static sd_rsp_type_t sd_cmd_to_sendingdata(SDState *sd, SDRequest req,
uint64_t start,
const void *data, size_t size)
@@ -1930,6 +1945,19 @@ send_response:
return rsplen;
}
+/* Return true when buffer consumed */
+__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 consumed */
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 2/7] hw/sd/sdcard: Duplicate WRITE_SINGLE_BLOCK / WRITE_MULTIPLE_BLOCK cases
2024-06-25 7:34 [PATCH 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 1/7] hw/sd/sdcard: Introduce sd_cmd_to_receivingdata / sd_generic_write_byte Philippe Mathieu-Daudé
@ 2024-06-25 7:34 ` Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 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-25 7:34 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Philippe Mathieu-Daudé, Bin Meng,
Cédric Le Goater
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 7fea0afb62..8c30826754 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1437,6 +1437,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 3/7] hw/sd/sdcard: Convert WRITE_SINGLE_BLOCK to generic_write_byte (CMD24)
2024-06-25 7:34 [PATCH 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 1/7] hw/sd/sdcard: Introduce sd_cmd_to_receivingdata / sd_generic_write_byte Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 2/7] hw/sd/sdcard: Duplicate WRITE_SINGLE_BLOCK / WRITE_MULTIPLE_BLOCK cases Philippe Mathieu-Daudé
@ 2024-06-25 7:34 ` Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 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-25 7:34 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Philippe Mathieu-Daudé, Bin Meng,
Cédric Le Goater
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 8c30826754..fff4be3ae2 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1081,7 +1081,6 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req)
return sd_illegal;
}
-__attribute__((unused))
static sd_rsp_type_t sd_cmd_to_receivingdata(SDState *sd, SDRequest req,
uint64_t start, size_t size)
{
@@ -1446,10 +1445,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;
@@ -1459,7 +1454,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;
@@ -1975,7 +1970,6 @@ send_response:
}
/* Return true when buffer consumed */
-__attribute__((unused))
static bool sd_generic_write_byte(SDState *sd, uint8_t value)
{
sd->data[sd->data_offset] = value;
@@ -2021,8 +2015,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 4/7] hw/sd/sdcard: Convert PROGRAM_CID to generic_write_byte (CMD26)
2024-06-25 7:34 [PATCH 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2024-06-25 7:34 ` [PATCH 3/7] hw/sd/sdcard: Convert WRITE_SINGLE_BLOCK to generic_write_byte (CMD24) Philippe Mathieu-Daudé
@ 2024-06-25 7:34 ` Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 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-25 7:34 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Philippe Mathieu-Daudé, Bin Meng,
Cédric Le Goater
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 fff4be3ae2..9db3b32b0b 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1491,17 +1491,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) {
@@ -2064,8 +2054,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 5/7] hw/sd/sdcard: Convert PROGRAM_CSD to generic_write_byte (CMD27)
2024-06-25 7:34 [PATCH 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2024-06-25 7:34 ` [PATCH 4/7] hw/sd/sdcard: Convert PROGRAM_CID to generic_write_byte (CMD26) Philippe Mathieu-Daudé
@ 2024-06-25 7:34 ` Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 6/7] hw/sd/sdcard: Convert LOCK_UNLOCK to generic_write_byte (CMD42) Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 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-25 7:34 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Philippe Mathieu-Daudé, Bin Meng,
Cédric Le Goater
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 9db3b32b0b..b0f29034c0 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1494,17 +1494,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 */
@@ -2072,8 +2062,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 6/7] hw/sd/sdcard: Convert LOCK_UNLOCK to generic_write_byte (CMD42)
2024-06-25 7:34 [PATCH 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2024-06-25 7:34 ` [PATCH 5/7] hw/sd/sdcard: Convert PROGRAM_CSD to generic_write_byte (CMD27) Philippe Mathieu-Daudé
@ 2024-06-25 7:34 ` Philippe Mathieu-Daudé
2024-06-25 7:34 ` [PATCH 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-25 7:34 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Philippe Mathieu-Daudé, Bin Meng,
Cédric Le Goater
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 b0f29034c0..82b44b65e0 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1604,17 +1604,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 */
@@ -2085,8 +2075,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 7/7] hw/sd/sdcard: Convert GEN_CMD to generic_write_byte (CMD56)
2024-06-25 7:34 [PATCH 0/7] hw/sd/sd: Introduce sd_cmd_to_receivingdata() / sd_generic_write_byte() Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2024-06-25 7:34 ` [PATCH 6/7] hw/sd/sdcard: Convert LOCK_UNLOCK to generic_write_byte (CMD42) Philippe Mathieu-Daudé
@ 2024-06-25 7:34 ` Philippe Mathieu-Daudé
6 siblings, 0 replies; 8+ messages in thread
From: Philippe Mathieu-Daudé @ 2024-06-25 7:34 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Philippe Mathieu-Daudé, Bin Meng,
Cédric Le Goater
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 82b44b65e0..fe2210d65a 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -1633,14 +1633,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;
@@ -2085,9 +2083,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