1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 *
22 * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 *
30 * Start of crcmodel.c
31 *
32 *
33 * Author : Ross Williams (ross@guest.adelaide.edu.au.).
34 * Date : 3 June 1993.
35 * Status : Public domain.
36 *
37 * Description : This is the implementation (.c) file for the reference
38 * implementation of the Rocksoft^tm Model CRC Algorithm. For more
39 * information on the Rocksoft^tm Model CRC Algorithm, see the document
40 * titled "A Painless Guide to CRC Error Detection Algorithms" by Ross
41 * Williams (ross@guest.adelaide.edu.au.). This document is likely to be in
42 * "ftp.adelaide.edu.au/pub/rocksoft".
43 *
44 * Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia.
45 *
46 *
47 *
48 * Implementation Notes
49 * --------------------
50 * To avoid inconsistencies, the specification of each function is not echoed
51 * here. See the header file for a description of these functions.
52 * This package is light on checking because I want to keep it short and
53 * simple and portable (i.e. it would be too messy to distribute my entire
54 * C culture (e.g. assertions package) with this package.
55 *
56 *
57 */
58
59 #include "crcmodel.h"
60
61 /* The following definitions make the code more readable. */
62
63 #define BITMASK(X) (1L << (X))
64 #define MASK32 0xFFFFFFFFL
65 #define LOCAL static
66
67 LOCAL uint32_t reflect P_((uint32_t v, int b));
68 LOCAL uint32_t
reflect(v,b)69 reflect(v, b)
70 /* Returns the value v with the bottom b [0,32] bits reflected. */
71 /* Example: reflect(0x3e23L,3) == 0x3e26 */
72 uint32_t v;
73 int b;
74 {
75 int i;
76 uint32_t t = v;
77 for (i = 0; i < b; i++) {
78 if (t & 1L)
79 v |= BITMASK((b-1)-i);
80 else
81 v &= ~BITMASK((b-1)-i);
82 t >>= 1;
83 }
84 return (v);
85 }
86
87 LOCAL uint32_t widmask P_((p_cm_t));
88 LOCAL uint32_t
widmask(p_cm)89 widmask(p_cm)
90 /* Returns a longword whose value is (2^p_cm->cm_width)-1. */
91 /* The trick is to do this portably (e.g. without doing <<32). */
92 p_cm_t p_cm;
93 {
94 return ((((1L<<(p_cm->cm_width-1))-1L)<<1)|1L);
95 }
96
97 void
cm_ini(p_cm)98 cm_ini(p_cm)
99 p_cm_t p_cm;
100 {
101 p_cm->cm_reg = p_cm->cm_init;
102 }
103
104 void
cm_nxt(p_cm,ch)105 cm_nxt(p_cm, ch)
106 p_cm_t p_cm;
107 int ch;
108 {
109 int i;
110 uint32_t uch = (uint32_t)ch;
111 uint32_t topbit = BITMASK(p_cm->cm_width-1);
112
113 if (p_cm->cm_refin)
114 uch = reflect(uch, 8);
115
116 p_cm->cm_reg ^= (uch << (p_cm->cm_width-8));
117 for (i = 0; i < 8; i++) {
118 if (p_cm->cm_reg & topbit)
119 p_cm->cm_reg = (p_cm->cm_reg << 1) ^ p_cm->cm_poly;
120 else
121 p_cm->cm_reg <<= 1;
122
123 p_cm->cm_reg &= widmask(p_cm);
124 }
125 }
126
127 void
cm_blk(p_cm,blk_adr,blk_len)128 cm_blk(p_cm, blk_adr, blk_len)
129 p_cm_t p_cm;
130 p_ubyte_ blk_adr;
131 uint32_t blk_len;
132 {
133 while (blk_len--)
134 cm_nxt(p_cm, *blk_adr++);
135 }
136
137 uint32_t
cm_crc(p_cm)138 cm_crc(p_cm)
139 p_cm_t p_cm;
140 {
141 if (p_cm->cm_refot)
142 return (p_cm->cm_xorot ^ reflect(p_cm->cm_reg, p_cm->cm_width));
143 else
144 return (p_cm->cm_xorot ^ p_cm->cm_reg);
145 }
146
147 uint32_t
cm_tab(p_cm,index)148 cm_tab(p_cm, index)
149 p_cm_t p_cm;
150 int index;
151 {
152 int i;
153 uint32_t r;
154 uint32_t topbit = BITMASK(p_cm->cm_width-1);
155 uint32_t inbyte = (uint32_t)index;
156
157 if (p_cm->cm_refin)
158 inbyte = reflect(inbyte, 8);
159
160 r = inbyte << (p_cm->cm_width-8);
161 for (i = 0; i < 8; i++)
162 if (r & topbit)
163 r = (r << 1) ^ p_cm->cm_poly;
164 else
165 r <<= 1;
166
167 if (p_cm->cm_refin)
168 r = reflect(r, p_cm->cm_width);
169
170 return (r & widmask(p_cm));
171 }
172