4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
32 * Author : Ross Williams (ross@guest.adelaide.edu.au.).
34 * Status : Public domain.
36 * Description : This is the implementation (.c) file for the reference
37 * implementation of the Rocksoft^tm Model CRC Algorithm. For more
38 * information on the Rocksoft^tm Model CRC Algorithm, see the document
39 * titled "A Painless Guide to CRC Error Detection Algorithms" by Ross
40 * Williams (ross@guest.adelaide.edu.au.). This document is likely to be in
41 * "ftp.adelaide.edu.au/pub/rocksoft".
43 * Note: Rocksoft is a trademark of Rocksoft Pty Ltd, Adelaide, Australia.
47 * Implementation Notes
48 * --------------------
49 * To avoid inconsistencies, the specification of each function is not echoed
50 * here. See the header file for a description of these functions.
51 * This package is light on checking because I want to keep it short and
52 * simple and portable (i.e. it would be too messy to distribute my entire
53 * C culture (e.g. assertions package) with this package.
60 /* The following definitions make the code more readable. */
62 #define BITMASK(X) (1L << (X))
63 #define MASK32 0xFFFFFFFFL
66 LOCAL
uint32_t reflect
P_((uint32_t v
, int b
));
69 /* Returns the value v with the bottom b [0,32] bits reflected. */
70 /* Example: reflect(0x3e23L,3) == 0x3e26 */
76 for (i
= 0; i
< b
; i
++) {
78 v
|= BITMASK((b
-1)-i
);
80 v
&= ~BITMASK((b
-1)-i
);
86 LOCAL
uint32_t widmask
P_((p_cm_t
));
89 /* Returns a longword whose value is (2^p_cm->cm_width)-1. */
90 /* The trick is to do this portably (e.g. without doing <<32). */
93 return ((((1L<<(p_cm
->cm_width
-1))-1L)<<1)|1L);
100 p_cm
->cm_reg
= p_cm
->cm_init
;
109 uint32_t uch
= (uint32_t)ch
;
110 uint32_t topbit
= BITMASK(p_cm
->cm_width
-1);
113 uch
= reflect(uch
, 8);
115 p_cm
->cm_reg
^= (uch
<< (p_cm
->cm_width
-8));
116 for (i
= 0; i
< 8; i
++) {
117 if (p_cm
->cm_reg
& topbit
)
118 p_cm
->cm_reg
= (p_cm
->cm_reg
<< 1) ^ p_cm
->cm_poly
;
122 p_cm
->cm_reg
&= widmask(p_cm
);
127 cm_blk(p_cm
, blk_adr
, blk_len
)
133 cm_nxt(p_cm
, *blk_adr
++);
141 return (p_cm
->cm_xorot
^ reflect(p_cm
->cm_reg
, p_cm
->cm_width
));
143 return (p_cm
->cm_xorot
^ p_cm
->cm_reg
);
153 uint32_t topbit
= BITMASK(p_cm
->cm_width
-1);
154 uint32_t inbyte
= (uint32_t)index
;
157 inbyte
= reflect(inbyte
, 8);
159 r
= inbyte
<< (p_cm
->cm_width
-8);
160 for (i
= 0; i
< 8; i
++)
162 r
= (r
<< 1) ^ p_cm
->cm_poly
;
167 r
= reflect(r
, p_cm
->cm_width
);
169 return (r
& widmask(p_cm
));