]> git.ipfire.org Git - people/ms/u-boot.git/blame - lib/crc32.c
NAND: add Toshiba TC58NVG0 identifier
[people/ms/u-boot.git] / lib / crc32.c
CommitLineData
affae2bf
WD
1/*
2 * This file is derived from crc32.c from the zlib-1.1.3 distribution
3 * by Jean-loup Gailly and Mark Adler.
4 */
5
6/* crc32.c -- compute the CRC-32 of a data stream
7 * Copyright (C) 1995-1998 Mark Adler
8 * For conditions of distribution and use, see copyright notice in zlib.h
9 */
10
3ee8c120 11#ifndef USE_HOSTCC
b3aff0cb 12#include <common.h>
affae2bf 13#endif
3ee8c120
JT
14#include <compiler.h>
15#include <u-boot/crc.h>
affae2bf 16
f3b6d528 17#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
1de6b28b 18#include <watchdog.h>
f3b6d528 19#endif
a31e091a 20#include "u-boot/zlib.h"
affae2bf
WD
21
22#define local static
23#define ZEXPORT /* empty */
affae2bf 24
3ee8c120
JT
25#define tole(x) cpu_to_le32(x)
26
affae2bf
WD
27#ifdef DYNAMIC_CRC_TABLE
28
29local int crc_table_empty = 1;
89cdab78 30local uint32_t crc_table[256];
affae2bf
WD
31local void make_crc_table OF((void));
32
33/*
34 Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
35 x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
36
37 Polynomials over GF(2) are represented in binary, one bit per coefficient,
38 with the lowest powers in the most significant bit. Then adding polynomials
39 is just exclusive-or, and multiplying a polynomial by x is a right shift by
40 one. If we call the above polynomial p, and represent a byte as the
41 polynomial q, also with the lowest power in the most significant bit (so the
42 byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
43 where a mod b means the remainder after dividing a by b.
44
45 This calculation is done using the shift-register method of multiplying and
46 taking the remainder. The register is initialized to zero, and for each
47 incoming bit, x^32 is added mod p to the register if the bit is a one (where
48 x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
49 x (which is shifting right by one and adding x^32 mod p if the bit shifted
50 out is a one). We start with the highest power (least significant bit) of
51 q and repeat for all eight bits of q.
52
53 The table is simply the CRC of all possible eight bit values. This is all
54 the information needed to generate CRC's on data a byte at a time for all
55 combinations of CRC register values and incoming bytes.
56*/
57local void make_crc_table()
58{
89cdab78 59 uint32_t c;
affae2bf 60 int n, k;
7ed40117 61 uLong poly; /* polynomial exclusive-or pattern */
affae2bf
WD
62 /* terms of polynomial defining this crc (except x^32): */
63 static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
64
65 /* make exclusive-or pattern from polynomial (0xedb88320L) */
66 poly = 0L;
67 for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
68 poly |= 1L << (31 - p[n]);
69
70 for (n = 0; n < 256; n++)
71 {
72 c = (uLong)n;
73 for (k = 0; k < 8; k++)
74 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
3ee8c120 75 crc_table[n] = tole(c);
affae2bf
WD
76 }
77 crc_table_empty = 0;
78}
79#else
80/* ========================================================================
81 * Table of CRC-32's of all single-byte values (made by make_crc_table)
82 */
3ee8c120 83
89cdab78 84local const uint32_t crc_table[256] = {
3ee8c120
JT
85tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
86tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
87tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
88tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
89tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
90tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
91tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
92tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
93tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
94tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
95tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
96tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
97tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
98tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
99tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
100tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
101tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
102tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
103tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
104tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
105tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
106tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
107tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
108tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
109tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
110tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
111tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
112tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
113tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
114tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
115tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
116tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
117tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
118tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
119tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
120tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
121tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
122tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
123tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
124tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
125tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
126tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
127tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
128tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
129tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
130tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
131tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
132tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
133tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
134tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
135tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
136tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
137tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
138tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
139tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
140tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
141tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
142tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
143tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
144tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
145tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
146tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
147tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
148tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
affae2bf
WD
149};
150#endif
151
152#if 0
153/* =========================================================================
154 * This function can be used by asm versions of crc32()
155 */
89cdab78 156const uint32_t * ZEXPORT get_crc_table()
affae2bf
WD
157{
158#ifdef DYNAMIC_CRC_TABLE
159 if (crc_table_empty) make_crc_table();
160#endif
89cdab78 161 return (const uint32_t *)crc_table;
affae2bf
WD
162}
163#endif
164
165/* ========================================================================= */
322ff395 166# if __BYTE_ORDER == __LITTLE_ENDIAN
3ee8c120
JT
167# define DO_CRC(x) crc = tab[(crc ^ (x)) & 255] ^ (crc >> 8)
168# else
169# define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
170# endif
affae2bf
WD
171
172/* ========================================================================= */
affae2bf
WD
173
174/* No ones complement version. JFFS2 (and other things ?)
175 * don't use ones compliment in their CRC calculations.
176 */
89cdab78 177uint32_t ZEXPORT crc32_no_comp(uint32_t crc, const Bytef *buf, uInt len)
affae2bf 178{
3ee8c120
JT
179 const uint32_t *tab = crc_table;
180 const uint32_t *b =(const uint32_t *)buf;
181 size_t rem_len;
affae2bf
WD
182#ifdef DYNAMIC_CRC_TABLE
183 if (crc_table_empty)
184 make_crc_table();
185#endif
3ee8c120
JT
186 crc = cpu_to_le32(crc);
187 /* Align it */
188 if (((long)b) & 3 && len) {
189 uint8_t *p = (uint8_t *)b;
190 do {
191 DO_CRC(*p++);
192 } while ((--len) && ((long)p)&3);
193 b = (uint32_t *)p;
194 }
195
196 rem_len = len & 3;
197 len = len >> 2;
198 for (--b; len; --len) {
199 /* load data 32 bits wide, xor data 32 bits wide. */
200 crc ^= *++b; /* use pre increment for speed */
201 DO_CRC(0);
202 DO_CRC(0);
203 DO_CRC(0);
204 DO_CRC(0);
205 }
206 len = rem_len;
207 /* And the last few bytes */
208 if (len) {
209 uint8_t *p = (uint8_t *)(b + 1) - 1;
210 do {
211 DO_CRC(*++p); /* use pre increment for speed */
212 } while (--len);
affae2bf 213 }
affae2bf 214
3ee8c120 215 return le32_to_cpu(crc);
affae2bf 216}
3ee8c120 217#undef DO_CRC
affae2bf 218
3ee8c120
JT
219uint32_t ZEXPORT crc32 (uint32_t crc, const Bytef *p, uInt len)
220{
221 return crc32_no_comp(crc ^ 0xffffffffL, p, len) ^ 0xffffffffL;
222}
215b01bb
BS
223
224/*
225 * Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes
226 * of input.
227 */
03ccdbcd
WD
228uint32_t ZEXPORT crc32_wd (uint32_t crc,
229 const unsigned char *buf,
230 uInt len, uInt chunk_sz)
215b01bb
BS
231{
232#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
233 const unsigned char *end, *curr;
234 int chunk;
235
236 curr = buf;
237 end = buf + len;
238 while (curr < end) {
239 chunk = end - curr;
240 if (chunk > chunk_sz)
241 chunk = chunk_sz;
242 crc = crc32 (crc, curr, chunk);
243 curr += chunk;
244 WATCHDOG_RESET ();
245 }
246#else
7ed40117 247 crc = crc32 (crc, buf, len);
215b01bb
BS
248#endif
249
250 return crc;
251}