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