xref: /spdk/lib/util/crc32.c (revision 57fd99b91e71a4baa5543e19ff83958dc99d4dac)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2017 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #include "util_internal.h"
7 #include "crc_internal.h"
8 #include "spdk/crc32.h"
9 
10 void
11 crc32_table_init(struct spdk_crc32_table *table, uint32_t polynomial_reflect)
12 {
13 	int i, j;
14 	uint32_t val;
15 
16 	for (i = 0; i < 256; i++) {
17 		val = i;
18 		for (j = 0; j < 8; j++) {
19 			if (val & 1) {
20 				val = (val >> 1) ^ polynomial_reflect;
21 			} else {
22 				val = (val >> 1);
23 			}
24 		}
25 		table->table[i] = val;
26 	}
27 }
28 
29 #ifdef SPDK_HAVE_ARM_CRC
30 
31 uint32_t
32 crc32_update(const struct spdk_crc32_table *table, const void *buf, size_t len, uint32_t crc)
33 {
34 	size_t count_pre, count_post, count_mid;
35 	const uint64_t *dword_buf;
36 
37 	/* process the head and tail bytes separately to make the buf address
38 	 * passed to crc32_d is 8 byte aligned. This can avoid unaligned loads.
39 	 */
40 	count_pre = ((uint64_t)buf & 7) == 0 ? 0 : 8 - ((uint64_t)buf & 7);
41 	count_post = (uint64_t)(buf + len) & 7;
42 	count_mid = (len - count_pre - count_post) / 8;
43 
44 	while (count_pre--) {
45 		crc = __crc32b(crc, *(const uint8_t *)buf);
46 		buf++;
47 	}
48 
49 	dword_buf = (const uint64_t *)buf;
50 	while (count_mid--) {
51 		crc = __crc32d(crc, *dword_buf);
52 		dword_buf++;
53 	}
54 
55 	buf = dword_buf;
56 	while (count_post--) {
57 		crc = __crc32b(crc, *(const uint8_t *)buf);
58 		buf++;
59 	}
60 
61 	return crc;
62 }
63 
64 #else
65 
66 uint32_t
67 crc32_update(const struct spdk_crc32_table *table, const void *buf, size_t len, uint32_t crc)
68 {
69 	const uint8_t *buf_u8 = buf;
70 	size_t i;
71 
72 	for (i = 0; i < len; i++) {
73 		crc = (crc >> 8) ^ table->table[(crc ^ buf_u8[i]) & 0xff];
74 	}
75 
76 	return crc;
77 }
78 
79 #endif
80