Message ID | 20240628070216.92609-19-philmd@linaro.org |
---|---|
State | New |
Headers | show |
Series | hw/sd/sdcard: Add eMMC support | expand |
On 6/28/24 9:00 AM, Philippe Mathieu-Daudé wrote: > All commands switching from TRANSFER state to (sending)DATA > do the same: send stream of data on the DAT lines. Instead > of duplicating the same code many times, introduce 2 helpers: > - sd_cmd_to_sendingdata() on the I/O line setup the data to > be transferred, > - sd_generic_read_byte() on the DAT lines to fetch the data. > > Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> > --- > hw/sd/sd.c | 39 +++++++++++++++++++++++++++++++++++++++ > 1 file changed, 39 insertions(+) > > diff --git a/hw/sd/sd.c b/hw/sd/sd.c > index d85b2906f4..1a8d06804d 100644 > --- a/hw/sd/sd.c > +++ b/hw/sd/sd.c > @@ -142,8 +142,10 @@ struct SDState { > */ > bool expecting_acmd; > uint32_t blk_written; > + > uint64_t data_start; > uint32_t data_offset; > + size_t data_size; > uint8_t data[512]; > uint8_t vendor_data[512]; > > @@ -1083,6 +1085,29 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req) > return sd_illegal; > } > > +/* Configure fields for following sd_generic_read_byte() calls */ > +__attribute__((unused)) > +static sd_rsp_type_t sd_cmd_to_sendingdata(SDState *sd, SDRequest req, > + uint64_t start, > + const void *data, size_t size) > +{ > + if (sd->state != sd_transfer_state) { > + sd_invalid_state_for_cmd(sd, req); > + } > + > + sd->state = sd_sendingdata_state; > + sd->data_start = start; > + sd->data_offset = 0; > + if (data) { > + assert(size); Shouldn't we check for buffer overrun ? sizeof(sd->data) Thanks, C. > + memcpy(sd->data, data, size); > + } > + if (size) { > + sd->data_size = size; > + } > + return sd_r1; > +} > + > /* CMD0 */ > static sd_rsp_type_t sd_cmd_GO_IDLE_STATE(SDState *sd, SDRequest req) > { > @@ -1920,6 +1945,20 @@ send_response: > return rsplen; > } > > +/* Return true when buffer is consumed. Configured by sd_cmd_to_sendingdata() */ > +__attribute__((unused)) > +static bool sd_generic_read_byte(SDState *sd, uint8_t *value) > +{ > + *value = sd->data[sd->data_offset]; > + > + if (++sd->data_offset >= sd->data_size) { > + sd->state = sd_transfer_state; > + return true; > + } > + > + return false; > +} > + > void sd_write_byte(SDState *sd, uint8_t value) > { > int i;
diff --git a/hw/sd/sd.c b/hw/sd/sd.c index d85b2906f4..1a8d06804d 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -142,8 +142,10 @@ struct SDState { */ bool expecting_acmd; uint32_t blk_written; + uint64_t data_start; uint32_t data_offset; + size_t data_size; uint8_t data[512]; uint8_t vendor_data[512]; @@ -1083,6 +1085,29 @@ static sd_rsp_type_t sd_cmd_unimplemented(SDState *sd, SDRequest req) return sd_illegal; } +/* Configure fields for following sd_generic_read_byte() calls */ +__attribute__((unused)) +static sd_rsp_type_t sd_cmd_to_sendingdata(SDState *sd, SDRequest req, + uint64_t start, + const void *data, size_t size) +{ + if (sd->state != sd_transfer_state) { + sd_invalid_state_for_cmd(sd, req); + } + + sd->state = sd_sendingdata_state; + sd->data_start = start; + sd->data_offset = 0; + if (data) { + assert(size); + memcpy(sd->data, data, size); + } + if (size) { + sd->data_size = size; + } + return sd_r1; +} + /* CMD0 */ static sd_rsp_type_t sd_cmd_GO_IDLE_STATE(SDState *sd, SDRequest req) { @@ -1920,6 +1945,20 @@ send_response: return rsplen; } +/* Return true when buffer is consumed. Configured by sd_cmd_to_sendingdata() */ +__attribute__((unused)) +static bool sd_generic_read_byte(SDState *sd, uint8_t *value) +{ + *value = sd->data[sd->data_offset]; + + if (++sd->data_offset >= sd->data_size) { + sd->state = sd_transfer_state; + return true; + } + + return false; +} + void sd_write_byte(SDState *sd, uint8_t value) { int i;
All commands switching from TRANSFER state to (sending)DATA do the same: send stream of data on the DAT lines. Instead of duplicating the same code many times, introduce 2 helpers: - sd_cmd_to_sendingdata() on the I/O line setup the data to be transferred, - sd_generic_read_byte() on the DAT lines to fetch the data. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- hw/sd/sd.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)