Take those functions out of hw/sd/sd.c (via "sdmmc-internal.h") to be able to write QTests for them.
Signed-off-by: Philippe Mathieu-Daudé <f4...@amsat.org> --- hw/sd/sdmmc-internal.h | 22 ++++++++++++++++++++++ hw/sd/sd.c | 37 ------------------------------------- hw/sd/sdmmc-internal.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 37 deletions(-) diff --git a/hw/sd/sdmmc-internal.h b/hw/sd/sdmmc-internal.h index 9aa04766fc..62c0ff250d 100644 --- a/hw/sd/sdmmc-internal.h +++ b/hw/sd/sdmmc-internal.h @@ -36,4 +36,26 @@ const char *sd_cmd_name(uint8_t cmd); */ const char *sd_acmd_name(uint8_t cmd); +/** + * sd_crc7: + * @data: pointer to the data buffer + * @data_len: data length + * + * Calculate the 7-bit CRC of a SD frame. + * + * Returns: The frame CRC. + */ +uint8_t sd_crc7(const void *data, size_t data_len); + +/** + * sd_crc16: + * @data: pointer to the data buffer + * @data_len: data length + * + * Calculate the 16-bit CRC of a SD data frame. + * + * Returns: The frame CRC. + */ +uint16_t sd_crc16(const void *data, size_t data_len); + #endif diff --git a/hw/sd/sd.c b/hw/sd/sd.c index a28ef8de5e..11b4606051 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -237,43 +237,6 @@ static const int sd_cmd_class[SDMMC_CMD_MAX] = { 7, 7, 10, 7, 9, 9, 9, 8, 8, 10, 8, 8, 8, 8, 8, 8, }; -static uint8_t sd_crc7(const void *message, size_t width) -{ - int i, bit; - uint8_t shift_reg = 0x00; - const uint8_t *msg = (const uint8_t *)message; - - for (i = 0; i < width; i++, msg++) { - for (bit = 7; bit >= 0; bit--) { - shift_reg <<= 1; - if ((shift_reg >> 7) ^ ((*msg >> bit) & 1)) { - shift_reg ^= 0x89; - } - } - } - - return shift_reg; -} - -static uint16_t sd_crc16(const void *message, size_t width) -{ - int i, bit; - uint16_t shift_reg = 0x0000; - const uint16_t *msg = (const uint16_t *)message; - width <<= 1; - - for (i = 0; i < width; i++, msg++) { - for (bit = 15; bit >= 0; bit--) { - shift_reg <<= 1; - if ((shift_reg >> 15) ^ ((*msg >> bit) & 1)) { - shift_reg ^= 0x1011; - } - } - } - - return shift_reg; -} - #define OCR_POWER_DELAY_NS 500000 /* 0.5ms */ FIELD(OCR, VDD_VOLTAGE_WINDOW, 0, 24) diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c index 2053def3f1..69ad0a99e6 100644 --- a/hw/sd/sdmmc-internal.c +++ b/hw/sd/sdmmc-internal.c @@ -70,3 +70,41 @@ const char *sd_acmd_name(uint8_t cmd) return acmd_abbrev[cmd] ? acmd_abbrev[cmd] : "UNKNOWN_ACMD"; } + +/* 7 bit CRC with polynomial x^7 + x^3 + 1 */ +uint8_t sd_crc7(const void *message, size_t width) +{ + int i, bit; + uint8_t shift_reg = 0x00; + const uint8_t *msg = (const uint8_t *)message; + + for (i = 0; i < width; i++, msg++) { + for (bit = 7; bit >= 0; bit--) { + shift_reg <<= 1; + if ((shift_reg >> 7) ^ ((*msg >> bit) & 1)) { + shift_reg ^= 0x89; + } + } + } + + return shift_reg; +} + +uint16_t sd_crc16(const void *message, size_t width) +{ + int i, bit; + uint16_t shift_reg = 0x0000; + const uint16_t *msg = (const uint16_t *)message; + width <<= 1; + + for (i = 0; i < width; i++, msg++) { + for (bit = 15; bit >= 0; bit--) { + shift_reg <<= 1; + if ((shift_reg >> 15) ^ ((*msg >> bit) & 1)) { + shift_reg ^= 0x1011; + } + } + } + + return shift_reg; +} -- 2.17.0