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.buschsieweke@ovgu.de> Reviewed-on: https://review.openocd.org/c/openocd/+/7415 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
committed by
Antonio Borneo
parent
92dd917f5a
commit
6e67f1473a
@@ -0,0 +1,50 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2013-2014 by Franck Jullien *
|
||||
* elec4fun@gmail.com *
|
||||
* *
|
||||
* Copyright (C) 2022 Otto-von-Guericke-Universität Magdeburg *
|
||||
* marian.buschsieweke@ovgu.de *
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "crc32.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;
|
||||
}
|
||||
Reference in New Issue
Block a user