178acc472SPeter Tyser /*
278acc472SPeter Tyser * This file is derived from crc32.c from the zlib-1.1.3 distribution
378acc472SPeter Tyser * by Jean-loup Gailly and Mark Adler.
478acc472SPeter Tyser */
578acc472SPeter Tyser
678acc472SPeter Tyser /* crc32.c -- compute the CRC-32 of a data stream
778acc472SPeter Tyser * Copyright (C) 1995-1998 Mark Adler
878acc472SPeter Tyser * For conditions of distribution and use, see copyright notice in zlib.h
978acc472SPeter Tyser */
1078acc472SPeter Tyser
11*74a18ee8SSimon Glass #ifdef USE_HOSTCC
12*74a18ee8SSimon Glass #include <arpa/inet.h>
13*74a18ee8SSimon Glass #else
1478acc472SPeter Tyser #include <common.h>
1578acc472SPeter Tyser #endif
1678acc472SPeter Tyser #include <compiler.h>
1778acc472SPeter Tyser #include <u-boot/crc.h>
1878acc472SPeter Tyser
1978acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
2078acc472SPeter Tyser #include <watchdog.h>
2178acc472SPeter Tyser #endif
2278acc472SPeter Tyser #include "u-boot/zlib.h"
2378acc472SPeter Tyser
2478acc472SPeter Tyser #define local static
2578acc472SPeter Tyser #define ZEXPORT /* empty */
2678acc472SPeter Tyser
2778acc472SPeter Tyser #define tole(x) cpu_to_le32(x)
2878acc472SPeter Tyser
2978acc472SPeter Tyser #ifdef DYNAMIC_CRC_TABLE
3078acc472SPeter Tyser
3178acc472SPeter Tyser local int crc_table_empty = 1;
3278acc472SPeter Tyser local uint32_t crc_table[256];
3378acc472SPeter Tyser local void make_crc_table OF((void));
3478acc472SPeter Tyser
3578acc472SPeter Tyser /*
3678acc472SPeter Tyser Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
3778acc472SPeter Tyser 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.
3878acc472SPeter Tyser
3978acc472SPeter Tyser Polynomials over GF(2) are represented in binary, one bit per coefficient,
4078acc472SPeter Tyser with the lowest powers in the most significant bit. Then adding polynomials
4178acc472SPeter Tyser is just exclusive-or, and multiplying a polynomial by x is a right shift by
4278acc472SPeter Tyser one. If we call the above polynomial p, and represent a byte as the
4378acc472SPeter Tyser polynomial q, also with the lowest power in the most significant bit (so the
4478acc472SPeter Tyser byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
4578acc472SPeter Tyser where a mod b means the remainder after dividing a by b.
4678acc472SPeter Tyser
4778acc472SPeter Tyser This calculation is done using the shift-register method of multiplying and
4878acc472SPeter Tyser taking the remainder. The register is initialized to zero, and for each
4978acc472SPeter Tyser incoming bit, x^32 is added mod p to the register if the bit is a one (where
5078acc472SPeter Tyser x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
5178acc472SPeter Tyser x (which is shifting right by one and adding x^32 mod p if the bit shifted
5278acc472SPeter Tyser out is a one). We start with the highest power (least significant bit) of
5378acc472SPeter Tyser q and repeat for all eight bits of q.
5478acc472SPeter Tyser
5578acc472SPeter Tyser The table is simply the CRC of all possible eight bit values. This is all
5678acc472SPeter Tyser the information needed to generate CRC's on data a byte at a time for all
5778acc472SPeter Tyser combinations of CRC register values and incoming bytes.
5878acc472SPeter Tyser */
make_crc_table()5978acc472SPeter Tyser local void make_crc_table()
6078acc472SPeter Tyser {
6178acc472SPeter Tyser uint32_t c;
6278acc472SPeter Tyser int n, k;
6378acc472SPeter Tyser uLong poly; /* polynomial exclusive-or pattern */
6478acc472SPeter Tyser /* terms of polynomial defining this crc (except x^32): */
6578acc472SPeter Tyser static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
6678acc472SPeter Tyser
6778acc472SPeter Tyser /* make exclusive-or pattern from polynomial (0xedb88320L) */
6878acc472SPeter Tyser poly = 0L;
6978acc472SPeter Tyser for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
7078acc472SPeter Tyser poly |= 1L << (31 - p[n]);
7178acc472SPeter Tyser
7278acc472SPeter Tyser for (n = 0; n < 256; n++)
7378acc472SPeter Tyser {
7478acc472SPeter Tyser c = (uLong)n;
7578acc472SPeter Tyser for (k = 0; k < 8; k++)
7678acc472SPeter Tyser c = c & 1 ? poly ^ (c >> 1) : c >> 1;
7778acc472SPeter Tyser crc_table[n] = tole(c);
7878acc472SPeter Tyser }
7978acc472SPeter Tyser crc_table_empty = 0;
8078acc472SPeter Tyser }
8178acc472SPeter Tyser #else
8278acc472SPeter Tyser /* ========================================================================
8378acc472SPeter Tyser * Table of CRC-32's of all single-byte values (made by make_crc_table)
8478acc472SPeter Tyser */
8578acc472SPeter Tyser
8678acc472SPeter Tyser local const uint32_t crc_table[256] = {
8778acc472SPeter Tyser tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL),
8878acc472SPeter Tyser tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L),
8978acc472SPeter Tyser tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L),
9078acc472SPeter Tyser tole(0x09b64c2bL), tole(0x7eb17cbdL), tole(0xe7b82d07L), tole(0x90bf1d91L),
9178acc472SPeter Tyser tole(0x1db71064L), tole(0x6ab020f2L), tole(0xf3b97148L), tole(0x84be41deL),
9278acc472SPeter Tyser tole(0x1adad47dL), tole(0x6ddde4ebL), tole(0xf4d4b551L), tole(0x83d385c7L),
9378acc472SPeter Tyser tole(0x136c9856L), tole(0x646ba8c0L), tole(0xfd62f97aL), tole(0x8a65c9ecL),
9478acc472SPeter Tyser tole(0x14015c4fL), tole(0x63066cd9L), tole(0xfa0f3d63L), tole(0x8d080df5L),
9578acc472SPeter Tyser tole(0x3b6e20c8L), tole(0x4c69105eL), tole(0xd56041e4L), tole(0xa2677172L),
9678acc472SPeter Tyser tole(0x3c03e4d1L), tole(0x4b04d447L), tole(0xd20d85fdL), tole(0xa50ab56bL),
9778acc472SPeter Tyser tole(0x35b5a8faL), tole(0x42b2986cL), tole(0xdbbbc9d6L), tole(0xacbcf940L),
9878acc472SPeter Tyser tole(0x32d86ce3L), tole(0x45df5c75L), tole(0xdcd60dcfL), tole(0xabd13d59L),
9978acc472SPeter Tyser tole(0x26d930acL), tole(0x51de003aL), tole(0xc8d75180L), tole(0xbfd06116L),
10078acc472SPeter Tyser tole(0x21b4f4b5L), tole(0x56b3c423L), tole(0xcfba9599L), tole(0xb8bda50fL),
10178acc472SPeter Tyser tole(0x2802b89eL), tole(0x5f058808L), tole(0xc60cd9b2L), tole(0xb10be924L),
10278acc472SPeter Tyser tole(0x2f6f7c87L), tole(0x58684c11L), tole(0xc1611dabL), tole(0xb6662d3dL),
10378acc472SPeter Tyser tole(0x76dc4190L), tole(0x01db7106L), tole(0x98d220bcL), tole(0xefd5102aL),
10478acc472SPeter Tyser tole(0x71b18589L), tole(0x06b6b51fL), tole(0x9fbfe4a5L), tole(0xe8b8d433L),
10578acc472SPeter Tyser tole(0x7807c9a2L), tole(0x0f00f934L), tole(0x9609a88eL), tole(0xe10e9818L),
10678acc472SPeter Tyser tole(0x7f6a0dbbL), tole(0x086d3d2dL), tole(0x91646c97L), tole(0xe6635c01L),
10778acc472SPeter Tyser tole(0x6b6b51f4L), tole(0x1c6c6162L), tole(0x856530d8L), tole(0xf262004eL),
10878acc472SPeter Tyser tole(0x6c0695edL), tole(0x1b01a57bL), tole(0x8208f4c1L), tole(0xf50fc457L),
10978acc472SPeter Tyser tole(0x65b0d9c6L), tole(0x12b7e950L), tole(0x8bbeb8eaL), tole(0xfcb9887cL),
11078acc472SPeter Tyser tole(0x62dd1ddfL), tole(0x15da2d49L), tole(0x8cd37cf3L), tole(0xfbd44c65L),
11178acc472SPeter Tyser tole(0x4db26158L), tole(0x3ab551ceL), tole(0xa3bc0074L), tole(0xd4bb30e2L),
11278acc472SPeter Tyser tole(0x4adfa541L), tole(0x3dd895d7L), tole(0xa4d1c46dL), tole(0xd3d6f4fbL),
11378acc472SPeter Tyser tole(0x4369e96aL), tole(0x346ed9fcL), tole(0xad678846L), tole(0xda60b8d0L),
11478acc472SPeter Tyser tole(0x44042d73L), tole(0x33031de5L), tole(0xaa0a4c5fL), tole(0xdd0d7cc9L),
11578acc472SPeter Tyser tole(0x5005713cL), tole(0x270241aaL), tole(0xbe0b1010L), tole(0xc90c2086L),
11678acc472SPeter Tyser tole(0x5768b525L), tole(0x206f85b3L), tole(0xb966d409L), tole(0xce61e49fL),
11778acc472SPeter Tyser tole(0x5edef90eL), tole(0x29d9c998L), tole(0xb0d09822L), tole(0xc7d7a8b4L),
11878acc472SPeter Tyser tole(0x59b33d17L), tole(0x2eb40d81L), tole(0xb7bd5c3bL), tole(0xc0ba6cadL),
11978acc472SPeter Tyser tole(0xedb88320L), tole(0x9abfb3b6L), tole(0x03b6e20cL), tole(0x74b1d29aL),
12078acc472SPeter Tyser tole(0xead54739L), tole(0x9dd277afL), tole(0x04db2615L), tole(0x73dc1683L),
12178acc472SPeter Tyser tole(0xe3630b12L), tole(0x94643b84L), tole(0x0d6d6a3eL), tole(0x7a6a5aa8L),
12278acc472SPeter Tyser tole(0xe40ecf0bL), tole(0x9309ff9dL), tole(0x0a00ae27L), tole(0x7d079eb1L),
12378acc472SPeter Tyser tole(0xf00f9344L), tole(0x8708a3d2L), tole(0x1e01f268L), tole(0x6906c2feL),
12478acc472SPeter Tyser tole(0xf762575dL), tole(0x806567cbL), tole(0x196c3671L), tole(0x6e6b06e7L),
12578acc472SPeter Tyser tole(0xfed41b76L), tole(0x89d32be0L), tole(0x10da7a5aL), tole(0x67dd4accL),
12678acc472SPeter Tyser tole(0xf9b9df6fL), tole(0x8ebeeff9L), tole(0x17b7be43L), tole(0x60b08ed5L),
12778acc472SPeter Tyser tole(0xd6d6a3e8L), tole(0xa1d1937eL), tole(0x38d8c2c4L), tole(0x4fdff252L),
12878acc472SPeter Tyser tole(0xd1bb67f1L), tole(0xa6bc5767L), tole(0x3fb506ddL), tole(0x48b2364bL),
12978acc472SPeter Tyser tole(0xd80d2bdaL), tole(0xaf0a1b4cL), tole(0x36034af6L), tole(0x41047a60L),
13078acc472SPeter Tyser tole(0xdf60efc3L), tole(0xa867df55L), tole(0x316e8eefL), tole(0x4669be79L),
13178acc472SPeter Tyser tole(0xcb61b38cL), tole(0xbc66831aL), tole(0x256fd2a0L), tole(0x5268e236L),
13278acc472SPeter Tyser tole(0xcc0c7795L), tole(0xbb0b4703L), tole(0x220216b9L), tole(0x5505262fL),
13378acc472SPeter Tyser tole(0xc5ba3bbeL), tole(0xb2bd0b28L), tole(0x2bb45a92L), tole(0x5cb36a04L),
13478acc472SPeter Tyser tole(0xc2d7ffa7L), tole(0xb5d0cf31L), tole(0x2cd99e8bL), tole(0x5bdeae1dL),
13578acc472SPeter Tyser tole(0x9b64c2b0L), tole(0xec63f226L), tole(0x756aa39cL), tole(0x026d930aL),
13678acc472SPeter Tyser tole(0x9c0906a9L), tole(0xeb0e363fL), tole(0x72076785L), tole(0x05005713L),
13778acc472SPeter Tyser tole(0x95bf4a82L), tole(0xe2b87a14L), tole(0x7bb12baeL), tole(0x0cb61b38L),
13878acc472SPeter Tyser tole(0x92d28e9bL), tole(0xe5d5be0dL), tole(0x7cdcefb7L), tole(0x0bdbdf21L),
13978acc472SPeter Tyser tole(0x86d3d2d4L), tole(0xf1d4e242L), tole(0x68ddb3f8L), tole(0x1fda836eL),
14078acc472SPeter Tyser tole(0x81be16cdL), tole(0xf6b9265bL), tole(0x6fb077e1L), tole(0x18b74777L),
14178acc472SPeter Tyser tole(0x88085ae6L), tole(0xff0f6a70L), tole(0x66063bcaL), tole(0x11010b5cL),
14278acc472SPeter Tyser tole(0x8f659effL), tole(0xf862ae69L), tole(0x616bffd3L), tole(0x166ccf45L),
14378acc472SPeter Tyser tole(0xa00ae278L), tole(0xd70dd2eeL), tole(0x4e048354L), tole(0x3903b3c2L),
14478acc472SPeter Tyser tole(0xa7672661L), tole(0xd06016f7L), tole(0x4969474dL), tole(0x3e6e77dbL),
14578acc472SPeter Tyser tole(0xaed16a4aL), tole(0xd9d65adcL), tole(0x40df0b66L), tole(0x37d83bf0L),
14678acc472SPeter Tyser tole(0xa9bcae53L), tole(0xdebb9ec5L), tole(0x47b2cf7fL), tole(0x30b5ffe9L),
14778acc472SPeter Tyser tole(0xbdbdf21cL), tole(0xcabac28aL), tole(0x53b39330L), tole(0x24b4a3a6L),
14878acc472SPeter Tyser tole(0xbad03605L), tole(0xcdd70693L), tole(0x54de5729L), tole(0x23d967bfL),
14978acc472SPeter Tyser tole(0xb3667a2eL), tole(0xc4614ab8L), tole(0x5d681b02L), tole(0x2a6f2b94L),
15078acc472SPeter Tyser tole(0xb40bbe37L), tole(0xc30c8ea1L), tole(0x5a05df1bL), tole(0x2d02ef8dL)
15178acc472SPeter Tyser };
15278acc472SPeter Tyser #endif
15378acc472SPeter Tyser
15478acc472SPeter Tyser #if 0
15578acc472SPeter Tyser /* =========================================================================
15678acc472SPeter Tyser * This function can be used by asm versions of crc32()
15778acc472SPeter Tyser */
15878acc472SPeter Tyser const uint32_t * ZEXPORT get_crc_table()
15978acc472SPeter Tyser {
16078acc472SPeter Tyser #ifdef DYNAMIC_CRC_TABLE
16178acc472SPeter Tyser if (crc_table_empty) make_crc_table();
16278acc472SPeter Tyser #endif
16378acc472SPeter Tyser return (const uint32_t *)crc_table;
16478acc472SPeter Tyser }
16578acc472SPeter Tyser #endif
16678acc472SPeter Tyser
16778acc472SPeter Tyser /* ========================================================================= */
16878acc472SPeter Tyser # if __BYTE_ORDER == __LITTLE_ENDIAN
16978acc472SPeter Tyser # define DO_CRC(x) crc = tab[(crc ^ (x)) & 255] ^ (crc >> 8)
17078acc472SPeter Tyser # else
17178acc472SPeter Tyser # define DO_CRC(x) crc = tab[((crc >> 24) ^ (x)) & 255] ^ (crc << 8)
17278acc472SPeter Tyser # endif
17378acc472SPeter Tyser
17478acc472SPeter Tyser /* ========================================================================= */
17578acc472SPeter Tyser
17678acc472SPeter Tyser /* No ones complement version. JFFS2 (and other things ?)
17778acc472SPeter Tyser * don't use ones compliment in their CRC calculations.
17878acc472SPeter Tyser */
crc32_no_comp(uint32_t crc,const Bytef * buf,uInt len)17978acc472SPeter Tyser uint32_t ZEXPORT crc32_no_comp(uint32_t crc, const Bytef *buf, uInt len)
18078acc472SPeter Tyser {
18178acc472SPeter Tyser const uint32_t *tab = crc_table;
18278acc472SPeter Tyser const uint32_t *b =(const uint32_t *)buf;
18378acc472SPeter Tyser size_t rem_len;
18478acc472SPeter Tyser #ifdef DYNAMIC_CRC_TABLE
18578acc472SPeter Tyser if (crc_table_empty)
18678acc472SPeter Tyser make_crc_table();
18778acc472SPeter Tyser #endif
18878acc472SPeter Tyser crc = cpu_to_le32(crc);
18978acc472SPeter Tyser /* Align it */
19078acc472SPeter Tyser if (((long)b) & 3 && len) {
19178acc472SPeter Tyser uint8_t *p = (uint8_t *)b;
19278acc472SPeter Tyser do {
19378acc472SPeter Tyser DO_CRC(*p++);
19478acc472SPeter Tyser } while ((--len) && ((long)p)&3);
19578acc472SPeter Tyser b = (uint32_t *)p;
19678acc472SPeter Tyser }
19778acc472SPeter Tyser
19878acc472SPeter Tyser rem_len = len & 3;
19978acc472SPeter Tyser len = len >> 2;
20078acc472SPeter Tyser for (--b; len; --len) {
20178acc472SPeter Tyser /* load data 32 bits wide, xor data 32 bits wide. */
20278acc472SPeter Tyser crc ^= *++b; /* use pre increment for speed */
20378acc472SPeter Tyser DO_CRC(0);
20478acc472SPeter Tyser DO_CRC(0);
20578acc472SPeter Tyser DO_CRC(0);
20678acc472SPeter Tyser DO_CRC(0);
20778acc472SPeter Tyser }
20878acc472SPeter Tyser len = rem_len;
20978acc472SPeter Tyser /* And the last few bytes */
21078acc472SPeter Tyser if (len) {
21178acc472SPeter Tyser uint8_t *p = (uint8_t *)(b + 1) - 1;
21278acc472SPeter Tyser do {
21378acc472SPeter Tyser DO_CRC(*++p); /* use pre increment for speed */
21478acc472SPeter Tyser } while (--len);
21578acc472SPeter Tyser }
21678acc472SPeter Tyser
21778acc472SPeter Tyser return le32_to_cpu(crc);
21878acc472SPeter Tyser }
21978acc472SPeter Tyser #undef DO_CRC
22078acc472SPeter Tyser
crc32(uint32_t crc,const Bytef * p,uInt len)22178acc472SPeter Tyser uint32_t ZEXPORT crc32 (uint32_t crc, const Bytef *p, uInt len)
22278acc472SPeter Tyser {
22378acc472SPeter Tyser return crc32_no_comp(crc ^ 0xffffffffL, p, len) ^ 0xffffffffL;
22478acc472SPeter Tyser }
22578acc472SPeter Tyser
22678acc472SPeter Tyser /*
22778acc472SPeter Tyser * Calculate the crc32 checksum triggering the watchdog every 'chunk_sz' bytes
22878acc472SPeter Tyser * of input.
22978acc472SPeter Tyser */
crc32_wd(uint32_t crc,const unsigned char * buf,uInt len,uInt chunk_sz)23078acc472SPeter Tyser uint32_t ZEXPORT crc32_wd (uint32_t crc,
23178acc472SPeter Tyser const unsigned char *buf,
23278acc472SPeter Tyser uInt len, uInt chunk_sz)
23378acc472SPeter Tyser {
23478acc472SPeter Tyser #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
23578acc472SPeter Tyser const unsigned char *end, *curr;
23678acc472SPeter Tyser int chunk;
23778acc472SPeter Tyser
23878acc472SPeter Tyser curr = buf;
23978acc472SPeter Tyser end = buf + len;
24078acc472SPeter Tyser while (curr < end) {
24178acc472SPeter Tyser chunk = end - curr;
24278acc472SPeter Tyser if (chunk > chunk_sz)
24378acc472SPeter Tyser chunk = chunk_sz;
24478acc472SPeter Tyser crc = crc32 (crc, curr, chunk);
24578acc472SPeter Tyser curr += chunk;
24678acc472SPeter Tyser WATCHDOG_RESET ();
24778acc472SPeter Tyser }
24878acc472SPeter Tyser #else
24978acc472SPeter Tyser crc = crc32 (crc, buf, len);
25078acc472SPeter Tyser #endif
25178acc472SPeter Tyser
25278acc472SPeter Tyser return crc;
25378acc472SPeter Tyser }
254d20a40deSSimon Glass
crc32_wd_buf(const unsigned char * input,unsigned int ilen,unsigned char * output,unsigned int chunk_sz)255d20a40deSSimon Glass void crc32_wd_buf(const unsigned char *input, unsigned int ilen,
256d20a40deSSimon Glass unsigned char *output, unsigned int chunk_sz)
257d20a40deSSimon Glass {
258d20a40deSSimon Glass uint32_t crc;
259d20a40deSSimon Glass
260d20a40deSSimon Glass crc = crc32_wd(0, input, ilen, chunk_sz);
261*74a18ee8SSimon Glass crc = htonl(crc);
262d20a40deSSimon Glass memcpy(output, &crc, sizeof(crc));
263d20a40deSSimon Glass }
264