qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 18/20] sdcard: Fix sd_crc16()


From: Philippe Mathieu-Daudé
Subject: [Qemu-devel] [PATCH 18/20] sdcard: Fix sd_crc16()
Date: Fri, 4 May 2018 12:59:16 -0300

The current sd_crc16() function does not pass the Spec test,
change it by a working one.

Code generated with pycrc v0.9.1 (https://pycrc.org) using the configuration:

 - Width         = 16
 - Poly          = 0x1021
 - XorIn         = 0x0000
 - ReflectIn     = False
 - XorOut        = 0x0000
 - ReflectOut    = False
 - Algorithm     = bit-by-bit-fast

  Copyright of the generated source code
  ======================================

  The code generated by pycrc is not considered a substantial portion of the
  software, therefore the licence does not cover the generated code, and the
  author of pycrc will not claim any copyright on the generated code.

Signed-off-by: Philippe Mathieu-Daudé <address@hidden>
---
 hw/sd/sdmmc-internal.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/hw/sd/sdmmc-internal.c b/hw/sd/sdmmc-internal.c
index 0e82e69d99..d6f9b3b51c 100644
--- a/hw/sd/sdmmc-internal.c
+++ b/hw/sd/sdmmc-internal.c
@@ -90,23 +90,31 @@ uint8_t sd_crc7(const void *message, size_t width)
     return shift_reg;
 }
 
-uint16_t sd_crc16(const void *message, size_t width)
+/* 16 bit XMODEM CRC (polynomial 0x1021) */
+uint16_t sd_crc16(const void *data, size_t data_len)
 {
-    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;
+    const unsigned char *d = (const unsigned char *)data;
+    uint16_t crc = 0x0000;
+    unsigned char c;
+    unsigned int i;
+    bool bit;
+
+    while (data_len--) {
+        c = *d++;
+        for (i = 0x80; i > 0; i >>= 1) {
+            bit = crc & 0x8000;
+            if (c & i) {
+                bit = !bit;
+            }
+            crc <<= 1;
+            if (bit) {
+                crc ^= 0x1021;
             }
         }
+        crc &= 0xffff;
     }
 
-    return shift_reg;
+    return crc;
 }
 
 static uint8_t sd_calc_frame48_crc7(uint8_t cmd, uint32_t arg, bool 
is_response)
-- 
2.17.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]