This is an automated email from Gerrit.

"Marian Buschsieweke <marian.buschsiew...@ovgu.de>" just uploaded a new patch 
set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7415

-- gerrit

commit fbd2c6f0f009123ed3e3eeb6881313ca3b5707e3
Author: Marian Buschsieweke <marian.buschsiew...@ovgu.de>
Date:   Thu Dec 22 13:20:07 2022 +0100

    helper: Add generic little endian CRC32 function
    
    This generalizes the little endian CRC32 function used in the OR1K
    target and moves it to a common helper, so that other places do not need
    to reinvent the wheel. It is directly used in the OR1K target.
    
    Change-Id: I0e55340281a5bfd80669bb1994f3a96fecc1248a
    Signed-off-by: Marian Buschsieweke <marian.buschsiew...@ovgu.de>

diff --git a/src/helper/Makefile.am b/src/helper/Makefile.am
index 7354f5422b..c4c60d96b4 100644
--- a/src/helper/Makefile.am
+++ b/src/helper/Makefile.am
@@ -9,6 +9,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la
        %D%/configuration.c \
        %D%/log.c \
        %D%/command.c \
+       %D%/crc32.c \
        %D%/time_support.c \
        %D%/replacements.c \
        %D%/fileio.c \
@@ -24,6 +25,7 @@ noinst_LTLIBRARIES += %D%/libhelper.la
        %D%/types.h \
        %D%/log.h \
        %D%/command.h \
+       %D%/crc32.h \
        %D%/time_support.h \
        %D%/replacements.h \
        %D%/fileio.h \
diff --git a/src/helper/crc32.c b/src/helper/crc32.c
new file mode 100644
index 0000000000..61518dfff8
--- /dev/null
+++ b/src/helper/crc32.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ *   Copyright (C) 2013-2014 by Franck Jullien                             *
+ *   elec4...@gmail.com                                                    *
+ *                                                                         *
+ *   Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg            *
+ *   marian.buschsiew...@ovgu.de                                           *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "crc32.h"
+#include <stdint.h>
+#include <stdint.h>
+#include <stddef.h>
+
+static uint32_t crc_le_step(uint32_t poly, uint32_t crc, uint32_t data_in,
+               unsigned int data_bits)
+{
+       for (unsigned int i = 0; i < data_bits; i++) {
+               uint32_t d, c;
+               d = ((data_in >> i) & 0x1) ? 0xffffffff : 0;
+               c = (crc & 0x1) ? 0xffffffff : 0;
+               crc = crc >> 1;
+               crc = crc ^ ((d ^ c) & poly);
+       }
+
+       return crc;
+}
+
+uint32_t crc32_le(uint32_t poly, uint32_t seed, const void *_data,
+               size_t data_len)
+{
+       if (((uintptr_t)_data & 0x3) || (data_len & 0x3)) {
+               /* data is unaligned, processing data one byte at a time */
+               const uint8_t *data = _data;
+               for (size_t i = 0; i < data_len; i++)
+                       seed = crc_le_step(poly, seed, data[i], 8);
+       } else {
+               /* data is aligned, processing 32 bit at a time */
+               data_len >>= 2;
+               const uint32_t *data = _data;
+               for (size_t i = 0; i < data_len; i++)
+                       seed = crc_le_step(poly, seed, data[i], 32);
+       }
+
+       return seed;
+}
diff --git a/src/helper/crc32.h b/src/helper/crc32.h
new file mode 100644
index 0000000000..8f077863a3
--- /dev/null
+++ b/src/helper/crc32.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/***************************************************************************
+ *   Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg            *
+ *   marian.buschsiew...@ovgu.de                                           *
+ ***************************************************************************/
+
+#ifndef OPENOCD_HELPER_CRC32_H
+#define OPENOCD_HELPER_CRC32_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+/** @file
+ * A generic CRC32 implementation
+ */
+
+/**
+ * CRC32 polynomial commonly used for little endian CRC32
+ */
+#define CRC32_POLY_LE  0xedb88320
+
+/**
+ * Calculate the CRC32 value of the given data
+ * @param      poly            The polynomial of the CRC
+ * @param      seed            The seed to use (mostly either `0` or 
`0xffffffff`)
+ * @param      data            The data to calculate the CRC32 of
+ * @param      data_len        The length of the data in @p data in bytes
+ * @return     The CRC value of the first @p data_len bytes at @p data
+ * @note       This function can be used to incrementally compute the CRC one
+ *                     chunk of data at a time by using the CRC32 of the 
previous chunk
+ *                     as @p seed for the next chunk.
+ */
+uint32_t crc32_le(uint32_t poly, uint32_t seed, const void *data,
+               size_t data_len);
+
+#endif /* OPENOCD_HELPER_CRC32_H */
diff --git a/src/target/openrisc/or1k_du_adv.c 
b/src/target/openrisc/or1k_du_adv.c
index e4c89e5b52..e4003a213d 100644
--- a/src/target/openrisc/or1k_du_adv.c
+++ b/src/target/openrisc/or1k_du_adv.c
@@ -22,8 +22,9 @@
 #include "or1k_du.h"
 #include "jsp_server.h"
 
-#include <target/target.h>
+#include <helper/crc32.h>
 #include <jtag/jtag.h>
+#include <target/target.h>
 
 #define JSP_BANNER "\n\r" \
                   "******************************\n\r" \
@@ -67,13 +68,6 @@
 #define DBG_CPU_CR_STALL               0x01
 #define DBG_CPU_CR_RESET               0x02
 
-/* Polynomial for the CRC calculation
- * Yes, it's backwards.  Yes, this is on purpose.
- * The hardware is designed this way to save on logic and routing,
- * and it's really all the same to us here.
- */
-#define ADBG_CRC_POLY                  0xedb88320
-
 /* These are for the internal registers in the Wishbone module
  * The first is the length of the index register,
  * the indexes of the various registers are defined after that.
@@ -133,20 +127,6 @@ static struct or1k_du or1k_du_adv;
 
 static const char * const chain_name[] = {"WISHBONE", "CPU0", "CPU1", "JSP"};
 
-static uint32_t adbg_compute_crc(uint32_t crc, uint32_t data_in,
-                                int length_bits)
-{
-       for (int i = 0; i < length_bits; i++) {
-               uint32_t d, c;
-               d = ((data_in >> i) & 0x1) ? 0xffffffff : 0;
-               c = (crc & 0x1) ? 0xffffffff : 0;
-               crc = crc >> 1;
-               crc = crc ^ ((d ^ c) & ADBG_CRC_POLY);
-       }
-
-       return crc;
-}
-
 static int find_status_bit(void *_buf, int len)
 {
        int i = 0;
@@ -522,9 +502,8 @@ retry_read_full:
        memcpy(data, in_buffer, total_size_bytes);
        memcpy(&crc_read, &in_buffer[total_size_bytes], 4);
 
-       uint32_t crc_calc = 0xffffffff;
-       for (int i = 0; i < total_size_bytes; i++)
-               crc_calc = adbg_compute_crc(crc_calc, data[i], 8);
+       uint32_t crc_calc = crc32_le(CRC32_POLY_LE, 0xffffffff, data,
+                       total_size_bytes);
 
        if (crc_calc != crc_read) {
                LOG_WARNING("CRC ERROR! Computed 0x%08" PRIx32 ", read CRC 
0x%08" PRIx32, crc_calc, crc_read);
@@ -650,9 +629,8 @@ retry_full_write:
        field[0].out_value = &value;
        field[0].in_value = NULL;
 
-       uint32_t crc_calc = 0xffffffff;
-       for (int i = 0; i < (count * size); i++)
-               crc_calc = adbg_compute_crc(crc_calc, data[i], 8);
+       uint32_t crc_calc = crc32_le(CRC32_POLY_LE, 0xffffffff, data,
+                       count * size);
 
        field[1].num_bits = count * size * 8;
        field[1].out_value = data;

-- 

Reply via email to