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