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