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