crc.c revision 1.2
1/*
2 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
3 *
4 * This software may be freely used, copied, modified, and distributed
5 * provided that the above copyright notice is preserved in all copies of the
6 * software.
7 */
8
9/* -*-C-*-
10 *
11 * $Revision: 1.2 $
12 *     $Date: 2004/05/21 20:23:36 $
13 *
14 *
15 * crc.c - provides some "standard" CRC calculation routines.
16 *
17 */
18#include "crc.h"    /* describes this code */
19
20/**********************************************************************/
21
22/*
23 * crc32                                                IEEE-802.3 32bit CRC
24 * -----                                                --------------------
25 */
26
27/* This table was generated by the "crctable" program */
28static const unsigned int crc32table[256] = {
29                   /* 0x00 */ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
30                   /* 0x04 */ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
31                   /* 0x08 */ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
32                   /* 0x0C */ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
33                   /* 0x10 */ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
34                   /* 0x14 */ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
35                   /* 0x18 */ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
36                   /* 0x1C */ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
37                   /* 0x20 */ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
38                   /* 0x24 */ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
39                   /* 0x28 */ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
40                   /* 0x2C */ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
41                   /* 0x30 */ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
42                   /* 0x34 */ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
43                   /* 0x38 */ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
44                   /* 0x3C */ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
45                   /* 0x40 */ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
46                   /* 0x44 */ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
47                   /* 0x48 */ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
48                   /* 0x4C */ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
49                   /* 0x50 */ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
50                   /* 0x54 */ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
51                   /* 0x58 */ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
52                   /* 0x5C */ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
53                   /* 0x60 */ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
54                   /* 0x64 */ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
55                   /* 0x68 */ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
56                   /* 0x6C */ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
57                   /* 0x70 */ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
58                   /* 0x74 */ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
59                   /* 0x78 */ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
60                   /* 0x7C */ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
61                   /* 0x80 */ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
62                   /* 0x84 */ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
63                   /* 0x88 */ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
64                   /* 0x8C */ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
65                   /* 0x90 */ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
66                   /* 0x94 */ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
67                   /* 0x98 */ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
68                   /* 0x9C */ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
69                   /* 0xA0 */ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
70                   /* 0xA4 */ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
71                   /* 0xA8 */ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
72                   /* 0xAC */ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
73                   /* 0xB0 */ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
74                   /* 0xB4 */ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
75                   /* 0xB8 */ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
76                   /* 0xBC */ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
77                   /* 0xC0 */ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
78                   /* 0xC4 */ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
79                   /* 0xC8 */ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
80                   /* 0xCC */ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
81                   /* 0xD0 */ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
82                   /* 0xD4 */ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
83                   /* 0xD8 */ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
84                   /* 0xDC */ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
85                   /* 0xE0 */ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
86                   /* 0xE4 */ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
87                   /* 0xE8 */ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
88                   /* 0xEC */ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
89                   /* 0xF0 */ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
90                   /* 0xF4 */ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
91                   /* 0xF8 */ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
92                   /* 0xFC */ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
93                                            };
94unsigned int crc32(unsigned char *address, unsigned int size, unsigned int crc)
95{
96#if 0
97  /* FAST, but bigger and only good for word-aligned data */
98  unsigned int *daddr = (unsigned int *)address;
99  unsigned int  data = FALSE; /* little-endian by default */
100
101 /*
102  * TODO: We should really get the current processor big- or
103  * little-endian state and set "data" accordingly.
104  */
105
106  /* Perform word loop to save on memory accesses */
107  if (data)
108    /* big-endian */
109    for (; (size > 0); size -= sizeof(unsigned int))
110    {
111      data = *daddr++;
112      crc = (((crc >> 8) & 0x00FFFFFF) ^
113             crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
114      crc = (((crc >> 8) & 0x00FFFFFF) ^
115             crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
116      crc = (((crc >> 8) & 0x00FFFFFF) ^
117             crc32table[(crc ^ ((data >>  8) & 0xFF)) & 0xFF]);
118      crc = (((crc >> 8) & 0x00FFFFFF) ^
119             crc32table[(crc ^ ((data >>  0) & 0xFF)) & 0xFF]);
120    }
121  else
122    for (; (size > 0); size -= sizeof(unsigned int))
123    {
124      data = *daddr++;
125      crc = (((crc >> 8) & 0x00FFFFFF) ^
126             crc32table[(crc ^ ((data >>  0) & 0xFF)) & 0xFF]);
127      crc = (((crc >> 8) & 0x00FFFFFF) ^
128             crc32table[(crc ^ ((data >>  8) & 0xFF)) & 0xFF]);
129      crc = (((crc >> 8) & 0x00FFFFFF) ^
130             crc32table[(crc ^ ((data >> 16) & 0xFF)) & 0xFF]);
131      crc = (((crc >> 8) & 0x00FFFFFF) ^
132             crc32table[(crc ^ ((data >> 24) & 0xFF)) & 0xFF]);
133    }
134#else
135  for (; (size > 0); size--)
136    /* byte loop */
137    crc = (((crc >> 8) & 0x00FFFFFF) ^
138           crc32table[(crc ^ *address++) & 0x000000FF]);
139#endif
140
141  return(crc);
142}
143
144/**********************************************************************/
145
146/*
147 * crc16                                                     16bit CRC-CCITT
148 * -----                                                     ---------------
149 * This function provides a table driven 16bit CRC generation for byte data.
150 * This CRC is also known as the HDLC CRC.
151 */
152/*
153 * 960201 KWelton
154 *
155 *TODO: Is this correct?  The compiler predefines __arm, *not* __ARM
156 */
157#ifdef __ARM
158/*
159 * To make the code quicker on the ARM, we double the table size and
160 * use integer slots rather than short slots for the table.
161 */
162static const unsigned int crctableA[16] = {
163#else
164static const unsigned short crctableA[16] = {
165#endif
166                                             0x0000,
167                                             0x1081,
168                                             0x2102,
169                                             0x3183,
170                                             0x4204,
171                                             0x5285,
172                                             0x6306,
173                                             0x7387,
174                                             0x8408,
175                                             0x9489,
176                                             0xA50A,
177                                             0xB58B,
178                                             0xC60C,
179                                             0xD68D,
180                                             0xE70E,
181                                             0xF78F
182                                            };
183
184#ifdef __ARM
185/* See comments above */
186static const unsigned int crctableB[16] = {
187#else
188static const unsigned short crctableB[16] = {
189#endif
190                                             0x0000,
191                                             0x1189,
192                                             0x2312,
193                                             0x329B,
194                                             0x4624,
195                                             0x57AD,
196                                             0x6536,
197                                             0x74BF,
198                                             0x8C48,
199                                             0x9DC1,
200                                             0xAF5A,
201                                             0xBED3,
202                                             0xCA6C,
203                                             0xDBE5,
204                                             0xE97E,
205                                             0xF8F7
206                                            };
207
208unsigned short crc16(unsigned char *address, unsigned int size,
209                     unsigned short crc)
210{
211  for (; (size > 0); size--)
212  {
213    /* byte loop */
214    unsigned char data = *address++; /* fetch the next data byte */
215
216    data ^= crc; /* EOR data with current CRC value */
217    crc = ((crctableA[(data & 0xF0) >> 4] ^ crctableB[data & 0x0F]) ^
218           (crc >> 8));
219  }
220
221  return(crc);
222}
223
224/**********************************************************************/
225
226#if 0 /* not required at the moment */
227
228/*
229 * elf_hash
230 * --------
231 * This function is derived from the one on page 68 of chapter of the "Unix
232 * SVR4 Programmer's Guide". It is used to generate a hash-code from a
233 * symbol name.
234 */
235unsigned int elf_hash(const unsigned char *name)
236{
237  unsigned int h = 0;
238  unsigned int g;
239
240  /* NULL pointer returns a hash of zero */
241  while (name && (*name))
242  {
243    h = ((h << 4) + *name++);
244
245    if (g = (h & 0xF0000000))
246      h ^= (g >> 24);
247
248    h &= ~g;
249  }
250
251  return(h);
252}
253#endif
254
255/**********************************************************************/
256
257/* EOF crc.c */
258