The 'read CID/CSD register' request returns a 136-bit frame containing those 128-bit registers.
Signed-off-by: Philippe Mathieu-Daudé <f4...@amsat.org> --- include/hw/sd/sd.h | 29 +++++++++++++++++++++++++++++ hw/sd/sdmmc-internal.c | 15 +++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h index 13de1b30c3..c76be51b32 100644 --- a/include/hw/sd/sd.h +++ b/include/hw/sd/sd.h @@ -91,6 +91,17 @@ typedef struct SDFrame48 { uint8_t crc; } SDFrame48; +/** + * SDFrame136: 136 bits CID or CSD responses + * + * @content: CID or CSD register + * @crc: 7-bit CRC checksum + */ +typedef struct SDFrame136 { + uint8_t content[15]; + uint8_t crc; +} SDFrame136; + typedef struct SDFrame48 SDRequest; typedef struct SDState SDState; @@ -193,6 +204,14 @@ void sd_prepare_frame48(SDFrame48 *frame, uint8_t cmd, uint32_t arg, */ void sd_update_frame48_checksum(SDFrame48 *frame, bool is_response); +/** + * sd_update_frame136_checksum: + * @frame: the #SDFrame136 to verify + * + * Update the 16-bit CRC checksum of a SD 136-bit frame. + */ +void sd_update_frame136_checksum(SDFrame136 *frame); + /** * sd_verify_frame48_checksum: * @frame: the #SDFrame48 to verify @@ -204,6 +223,16 @@ void sd_update_frame48_checksum(SDFrame48 *frame, bool is_response); */ bool sd_verify_frame48_checksum(SDFrame48 *frame, bool is_response); +/** + * sd_verify_frame136_checksum: + * @frame: the #SDFrame48 to verify + * + * Verify the 16-bit CRC checksum of a SD 136-bit frame. + * + * Returns: A boolean indicating whether the frame 16-bit CRC is correct. + */ +bool sd_verify_frame136_checksum(SDFrame136 *frame); + /* Legacy functions to be used only by non-qdevified callers */ SDState *sd_init(BlockBackend *bs, bool is_spi); int sd_do_command(SDState *sd, SDRequest *req, diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c index c990cc9e8e..68350a2304 100644 --- a/hw/sd/sdmmc-internal.c +++ b/hw/sd/sdmmc-internal.c @@ -117,6 +117,11 @@ static uint8_t sd_calc_frame48_crc7(uint8_t cmd, uint32_t arg, bool is_response) return sd_crc7(buffer, sizeof(buffer)); } +static uint8_t sd_calc_frame136_crc7(SDFrame136 *frame) +{ + return (sd_crc7(frame->content, sizeof(frame->content)) << 1) | 1; +} + bool sd_verify_frame48_checksum(SDFrame48 *frame, bool is_response) { uint8_t crc = sd_calc_frame48_crc7(frame->cmd, frame->arg, is_response); @@ -124,11 +129,21 @@ bool sd_verify_frame48_checksum(SDFrame48 *frame, bool is_response) return crc == frame->crc; } +bool sd_verify_frame136_checksum(SDFrame136 *frame) +{ + return sd_calc_frame136_crc7(frame) == frame->crc; +} + void sd_update_frame48_checksum(SDFrame48 *frame, bool is_response) { frame->crc = sd_calc_frame48_crc7(frame->cmd, frame->arg, is_response); } +void sd_update_frame136_checksum(SDFrame136 *frame) +{ + frame->crc = (sd_crc7(frame->content, sizeof(frame->content)) << 1) | 1; +} + void sd_prepare_frame48(SDFrame48 *frame, uint8_t cmd, uint32_t arg, bool is_response, bool gen_crc) { -- 2.17.0